当前位置:首页 > 编程教程 > java技术文章 > Java微信分享接口开发详解

Java微信分享接口开发示例效果

  • 发布时间:
  • 作者:码农之家
  • 点击:62

这篇文章主要知识点是关于java、java微信分享、java接口开发、微信公众平台 发送模板消息(Java接口开发) 的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

JavaScript编程全解
  • 类型:js编程大小:6.67 MB格式:PDF作者:井上诚一郎,土江拓郎,滨边将太,陈筱烟&
立即下载

Java微信分享接口开发详解

本文实例为大家分享了Java微信分享接口开发的具体代码,供大家参考,具体内容如下

Java微信分享,步骤是

1、根据当前的url,获取signature,nonceStr,timestamp 和appId。
2、通过signature,nonceStr,timestamp 和appId来配置微信 wx.config。
3、通过wx.ready实现微信分享功能。

1、html端

引入微信JS-SDK.

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
//分享核心js代码
$(document).ready(function () {
  //通过ajax,在页面加载的时候获取微信分享接口signature,nonceStr,timestamp 和appId
  $.ajax({
    type: "post",
    url: "/weixin/share",
    dataType: "json",
    data:"url="+window.location.href,
    success: function (data) {
      wx.config({
        debug: false,
        appId: data.appId,
        timestamp: data.timestamp,
        nonceStr: data.nonceStr,
        signature: data.signature,
        jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'hideAllNonBaseMenuItem', 'showMenuItems']
        // 功能列表,我们要使用JS-SDK的什么功能
      });
      wx.ready(function () {
        // 获取“分享给朋友”按钮点击状态及自定义分享内容接口
        wx.onMenuShareAppMessage({
          title: "分享自定义标题", // 分享标题
          desc: "分享自定义描述", // 分享描述
          link: "http://localhost/weixin/share?openId=1",//分享点击之后的链接
          imgUrl:'/images/photo/1.jpg', // 分享图标
          type: 'link', // 分享类型,music、video或link,不填默认为link
          success: function () {
            //成功之后的回调
          }
        });
        wx.hideAllNonBaseMenuItem();
        wx.showMenuItems({
          menuList: ['menuItem:share:appMessage', 'menuItem:share:timeline'] // 要隐藏的菜单项,只能隐藏“传播类”和“保护类”按钮,所有menu项见附录3
        });
        wx.onMenuShareTimeline({
          title: "分享自定义标题", // 分享标题
          desc: "分享自定义描述", // 分享描述
          link: "http://localhost/weixin/share?openId=1",//分享点击之后的链接
          imgUrl:'/images/photo/1.jpg', // 分享图标
          type: 'link', // 分享类型,music、video或link,不填默认为link
          success: function () {
            //成功之后的回调
          }
          cancel: function () {
            // 用户取消分享后执行的回调函数
          }
        });
      });
      wx.error(function (res) {
        //打印错误消息。及把 debug:false,设置为debug:ture就可以直接在网页上看到弹出的错误提示
      });
    }
  })
});

2、Java代码,获取 signature,nonceStr,timestamp 和appId

@RequestMapping(value = "/share", method = RequestMethod.POST)
  @ResponseBody
  public Map<String, Object> share(HttpServletRequest request) {
    String urlTemp = "http://" + request.getServerName() + request.getContextPath();
    String urlpath = "http://" + request.getServerName();
    String appUrl = request.getParameter("url");
    if (request.getParameter("code") != null) {
      appUrl += "&code=" + request.getParameter("code");
    }
    if (request.getParameter("state") != null) {
      appUrl += "&state=" + request.getParameter("state");
    }
    return WxConfigUtil.getSignature(appUrl, ContentValues.APPID, ContentValues.SECRET, urlTemp, urlpath);
  }

工具类我就把整个贴上来了,其中有些方法是没有用到的。

getSignature()整个方法是微信分享中的核心方法,用来获取signature,nonceStr,timestamp 和appId这几个核心参数。

package com.blog.common.util;

import com.alibaba.fastjson.JSONObject;
import com.blog.common.model.Token;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


/**
 * 公众平台通用接口工具类
 *
 * @author james
 * @date 2015-02-27
 */
public class WxConfigUtil {
  // 获取access_token的接口地址(GET) 限2000(次/天)
  public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
  // 获取jsapi_ticket的接口地址(GET) 限2000(次/天)
  public final static String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
  // 缓存添加的时间
  public static String cacheAddTime = null;
  // token,ticket缓存
  public static Map<String, Token> TOKEN_TICKET_CACHE = new HashMap<String, Token>();
  // token对应的key
  private static final String TOKEN = "token";
  // ticket对应的key
  private static final String TICKET = "ticket";

  /**
   * 外部获取签名入口类
   *
   * @param appUrl  应用的url
   * @return
   */
  public static Map<String, Object> getSignature(String appUrl, String appId, String secret, String url, String urlpath) {
    // 生成签名的随机串
    String noncestr = RandomUtil.getStringRandom(4);
    if (appUrl == null || "".equals(appUrl)) {
      return null;
    }
    String signature = null;
    Token accessTocken = getToken(appId, secret, System.currentTimeMillis() / 1000);
    Token accessTicket = getTicket(accessTocken.getToken(), System.currentTimeMillis() / 1000);
    signature = signature(accessTicket.getTicket(), cacheAddTime, noncestr, appUrl);
    System.out.println("-=-=-=-=-=-=-=-=appUrl:" + appUrl);
    System.out.println("-=-=-=-=-=-=-=-=token:" + accessTocken.getToken());
    System.out.println("-=-=-=-=-=-=-=-=ticket:" + accessTicket.getTicket());
    System.out.println("-=-=-=-=-=-=-=-=signature:" + signature);
    System.out.println("-=-=-=-=-=-=-=-=timestamp:" + cacheAddTime);
    Map<String, Object> map = new HashMap<>();
    map.put("appId", appId);
    map.put("timestamp", cacheAddTime);
    map.put("nonceStr", noncestr);
    map.put("appUrl", appUrl);
    map.put("signature", signature);
    map.put("url", url);
    map.put("urlpath", urlpath);
    return map;
  }

  /**
   * 获得Token
   *
   * @return
   */
  public static String getToken(String appId, String secret) {
    Token accessTocken = getToken(appId, secret, System.currentTimeMillis() / 1000);
    return accessTocken.getToken();
  }

  /**
   * 签名
   *
   * @param timestamp
   * @return
   */
  private static String signature(String jsapi_ticket, String timestamp, String noncestr, String url) {
    jsapi_ticket = "jsapi_ticket=" + jsapi_ticket;
    timestamp = "timestamp=" + timestamp;
    noncestr = "noncestr=" + noncestr;
    url = "url=" + url;
    String[] arr = new String[]{jsapi_ticket, noncestr, timestamp, url};
    // 将token、timestamp、nonce,url参数进行字典序排序
    Arrays.sort(arr);
    StringBuilder content = new StringBuilder();
    for (int i = 0; i < arr.length; i++) {
      content.append(arr[i]);
      if (i != arr.length - 1) {
        content.append("&");
      }
    }
    MessageDigest md = null;
    String tmpStr = null;

    try {
      md = MessageDigest.getInstance("SHA-1");
      // 将三个参数字符串拼接成一个字符串进行sha1加密
      byte[] digest = md.digest(content.toString().getBytes());
      tmpStr = byteToStr(digest);
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }

    content = null;
    return tmpStr;
  }

  /**
   * 获取access_token
   *
   * @param appid   凭证
   * @param appsecret 密钥
   * @return
   */
  public static Token getToken(String appid, String appsecret, long currentTime) {
    Token tockenTicketCache = getTokenTicket(TOKEN);
    Token Token = null;

    if (tockenTicketCache != null && (currentTime - tockenTicketCache.getAddTime() <= tockenTicketCache.getExpiresIn())) {// 缓存存在并且没过期
      System.out.println("==========缓存中token已获取时长为:" + (currentTime - tockenTicketCache.getAddTime()) + "毫秒,可以重新使用");
      return tockenTicketCache;
    }
    System.out.println("==========缓存中token不存在或已过期===============");
    String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
    JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
    // 如果请求成功
    if (null != jsonObject) {
      Token = new Token();
      Token.setToken(jsonObject.getString("access_token"));
      Token.setExpiresIn(jsonObject.getIntValue("expires_in") / 2);// 正常过期时间是7200秒,此处设置3600秒读取一次
      System.out.println("==========tocket缓存过期时间为:" + Token.getExpiresIn() + "毫秒");
      Token.setAddTime(currentTime);
      updateToken(TOKEN, Token);
    }
    return Token;
  }

  /**
   * 获取ticket
   *
   * @param token
   * @return
   */
  private static Token getTicket(String token, long currentTime) {
    Token tockenTicketCache = getTokenTicket(TICKET);
    Token Token = null;
    if (tockenTicketCache != null && (currentTime - tockenTicketCache.getAddTime() <= tockenTicketCache.getExpiresIn())) {// 缓存中有ticket
      System.out.println("==========缓存中ticket已获取时长为:" + (currentTime - tockenTicketCache.getAddTime()) + "毫秒,可以重新使用");
      return tockenTicketCache;
    }
    System.out.println("==========缓存中ticket不存在或已过期===============");
    String requestUrl = jsapi_ticket_url.replace("ACCESS_TOKEN", token);
    JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
    // 如果请求成功
    if (null != jsonObject) {
      Token = new Token();
      Token.setTicket(jsonObject.getString("ticket"));
      Token.setExpiresIn(jsonObject.getIntValue("expires_in") / 2);// 正常过期时间是7200秒,此处设置3600秒读取一次
      System.out.println("==========ticket缓存过期时间为:" + Token.getExpiresIn() + "毫秒");
      Token.setAddTime(currentTime);
      updateToken(TICKET, Token);
    }
    return Token;
  }

  /**
   * 发起https请求并获取结果
   *
   * @param requestUrl  请求地址
   * @param requestMethod 请求方式(GET、POST)
   * @param outputStr   提交的数据
   * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
   */
  private static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
    JSONObject jsonObject = null;
    StringBuffer buffer = new StringBuffer();
    try {
      // 创建SSLContext对象,并使用我们指定的信任管理器初始化
      TrustManager[] tm = {new MyX509TrustManager()};
      SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
      sslContext.init(null, tm, new java.security.SecureRandom());
      // 从上述SSLContext对象中得到SSLSocketFactory对象
      SSLSocketFactory ssf = sslContext.getSocketFactory();

      URL url = new URL(requestUrl);
      HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
      httpUrlConn.setSSLSocketFactory(ssf);

      httpUrlConn.setDoOutput(true);
      httpUrlConn.setDoInput(true);
      httpUrlConn.setUseCaches(false);
      // 设置请求方式(GET/POST)
      httpUrlConn.setRequestMethod(requestMethod);

      if ("GET".equalsIgnoreCase(requestMethod))
        httpUrlConn.connect();

      // 当有数据需要提交时
      if (null != outputStr) {
        OutputStream outputStream = httpUrlConn.getOutputStream();
        // 注意编码格式,防止中文乱码
        outputStream.write(outputStr.getBytes("UTF-8"));
        outputStream.close();
      }

      // 将返回的输入流转换成字符串
      InputStream inputStream = httpUrlConn.getInputStream();
      InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
      BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

      String str = null;
      while ((str = bufferedReader.readLine()) != null) {
        buffer.append(str);
      }
      bufferedReader.close();
      inputStreamReader.close();
      // 释放资源
      inputStream.close();
      inputStream = null;
      httpUrlConn.disconnect();
      jsonObject = JSONObject.parseObject(buffer.toString());
      // jsonObject = JSONObject.fromObject(buffer.toString());
    } catch (ConnectException ce) {
      System.out.println("Weixin server connection timed out.");
    } catch (Exception e) {
      System.out.println("https request error:{}" + e.getMessage());
    }
    return jsonObject;
  }

  /**
   * 将字节数组转换为十六进制字符串
   *
   * @param byteArray
   * @return
   */
  private static String byteToStr(byte[] byteArray) {
    String strDigest = "";
    for (int i = 0; i < byteArray.length; i++) {
      strDigest += byteToHexStr(byteArray[i]);
    }
    return strDigest;
  }

  /**
   * 将字节转换为十六进制字符串
   *
   * @param mByte
   * @return
   */
  private static String byteToHexStr(byte mByte) {

    char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    char[] tempArr = new char[2];
    tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
    tempArr[1] = Digit[mByte & 0X0F];

    String s = new String(tempArr);
    return s;
  }

  /**
   * 从缓存中读取token或者ticket
   *
   * @return
   */
  private static Token getTokenTicket(String key) {
    if (TOKEN_TICKET_CACHE != null && TOKEN_TICKET_CACHE.get(key) != null) {
      System.out.println("==========从缓存中获取到了" + key + "成功===============");
      return TOKEN_TICKET_CACHE.get(key);
    }
    return null;
  }

  /**
   * 更新缓存中token或者ticket
   *
   * @return
   */
  private static void updateToken(String key, Token accessTocken) {
    if (TOKEN_TICKET_CACHE != null && TOKEN_TICKET_CACHE.get(key) != null) {
      TOKEN_TICKET_CACHE.remove(key);
      System.out.println("==========从缓存中删除" + key + "成功===============");
    }
    TOKEN_TICKET_CACHE.put(key, accessTocken);
    cacheAddTime = String.valueOf(accessTocken.getAddTime());// 更新缓存修改的时间
    System.out.println("==========更新缓存中" + key + "成功===============");
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。

微信公众平台 发送模板消息(Java接口开发)

前言:最近一直再弄微信扫码推送图文消息和模板消息发送,感觉学习到了不少东西。今天先总结一下微信公众平台模板消息的发送。因为这个自己弄了很久,开始很多地方不明白,所以今天好好总结一下。

微信公众平台技术文档:模板消息接口

一、概述

模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。

关于使用规则,请注意:

1、所有服务号都可以在功能->添加功能插件处看到申请模板消息功能的入口,但只有认证后的服务号才可以申请模板消息的使用权限并获得该权限;
2、需要选择公众账号服务所处的2个行业,每月可更改1次所选行业;
3、在所选择行业的模板库中选用已有的模板进行调用;
4、每个账号可以同时使用25个模板。
5、当前每个账号的模板消息的日调用上限为10万次,单个模板没有特殊限制。【2014年11月18日将接口调用频率从默认的日1万次提升为日10万次,可在MP登录后的开发者中心查看】。当账号粉丝数超过10W/100W/1000W时,模板消息的日调用上限会相应提升,以公众号MP后台开发者中心页面中标明的数字为准。

关于接口文档,请注意:

1、模板消息调用时主要需要模板ID和模板中各参数的赋值内容;
2、模板中参数内容必须以”.DATA”结尾,否则视为保留字;
3、模板保留符号”{{ }}”。

看微信公众平台接口文档最开始我的内心是崩溃的,因为目录列表一开始就是设置所属行业,获取所属行业信息等。后来整理思路,我们主要负责的功能的实现,就不去考虑那么多其他的内容,直接弄模板消息的发送。但是发送模板之前有一个很重要的步骤,就是模板ID(template_id)。微信公众平台发送模板消息有严格的要求,参考模板消息运营规范。

二、模板消息的设计

这里是依靠微信公众平台测试公众号的模板消息接口来设计消息模板,通过行业类型来获取模板的同学还是参考微信公众平台的官方文档来学习。

1 新增模板消息

微信公众平台 发送模板消息(Java接口开发)

微信的测试公众号为我们提供了测试的消息模板,最多可添加10个(感觉够用,毕竟只是测试),新增测试模板。

微信公众平台 发送模板消息(Java接口开发)

(1)添加模板标题和模板内容

微信公众平台 发送模板消息(Java接口开发) 

模板标题比较好理解,模板内容需要设计参数,参数需以{{开头,以.DATA}}结尾。

例如:{{first.DATA}}

first就是我们接口传的参数。

{{first.DATA}} 
商品:{{keynote1.DATA}} 
价格:{{keynote2.DATA}} 
日期:{{keynote3.DATA}} 
{{remark.DATA}}

新增之后就可以看到模板记录,就有我们需要的模板ID了。有了模板ID我们就可以按照接下来的微信公众平台发送模板消息接口来实现我们的功能。

微信公众平台 发送模板消息(Java接口开发)

三、发送模板消息

1 接口调用请求说明

http请求方式: POST

https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN

2 POST数据说明

POST数据示例如下:

 {
      "touser":"OPENID",
      "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
      "url":"http://weixin.qq.com/download", 
      "miniprogram":{
       "appid":"xiaochengxuappid12345",
       "pagepath":"index?foo=bar"
      },     
      "data":{
          "first": {
            "value":"恭喜你购买成功!",
            "color":"#173177"
          },
          "keynote1":{
            "value":"巧克力",
            "color":"#173177"
          },
          "keynote2": {
            "value":"39.8元",
            "color":"#173177"
          },
          "keynote3": {
            "value":"2014年9月22日",
            "color":"#173177"
          },
          "remark":{
            "value":"欢迎再次购买!",
            "color":"#173177"
          }
      }
    }

3 参数说明

参数 是否必填 说明、
touser 接收者openid
template_id 模板ID
url 模板跳转链接
miniprogram 跳小程序所需数据,不需跳小程序可不用传该数据
appid 所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系)
pagepath 所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar)
data 模板数据

注:url和miniprogram都是非必填字段,若都不传则模板无跳转;若都传,会优先跳转至小程序。开发者可根据实际需要选择其中一种跳转方式即可。当用户的微信客户端版本不支持跳小程序时,将会跳转至url。

4 java接口开发

(1)封装请求参数Demo

public class TemplateData { 

  private String value; 
  private String color; 

  public String getValue() { 
    return value; 
  } 

  public void setValue(String value) { 
    this.value = value; 
  } 

  public String getColor() { 
    return color; 
  } 

  public void setColor(String color) { 
    this.color = color; 
  } 
}
public class WechatTemplate { 

  private String touser; 

  private String template_id; 

  private String url; 

  private Map<String, TemplateData> data; 

  public String getTouser() { 
    return touser; 
  } 

  public void setTouser(String touser) { 
    this.touser = touser; 
  } 

  public String getTemplate_id() { 
    return template_id; 
  } 

  public void setTemplate_id(String template_id) { 
    this.template_id = template_id; 
  } 

  public String getUrl() { 
    return url; 
  } 

  public void setUrl(String url) { 
    this.url = url; 
  } 

  public Map<String, TemplateData> getData() { 
    return data; 
  } 

  public void setData(Map<String, TemplateData> data) { 
    this.data = data; 
  } 
} 

(2)发送模板消息方法

public class TemplateMessageServiceImpl implements TemplateMessageService{

  private RestTemplate restTemplate ; 

  private String serviceHost = "https://api.weixin.qq.com";

  public TemplateMessageServiceImpl() {
    restTemplate = RestTemplateFactory.makeRestTemplate();
  }

  @Override
  public WeixinResponse sendTemplateMessage(String accessToken, WeixinTemplate weixinTemplate) {
    WeixinResponse weixinResponse = null;
    String url = new StringBuffer(serviceHost).append("/cgi-bin/message/template/send?access_token=")
        .append(accessToken).toString();
    weixinResponse = restTemplate.postForObject(url, weixinTemplate, WeixinResponse.class,new HashMap<String,String>());
    return weixinResponse;
  }

}

说明:简单理解模板消息发送,首先是获取accessToken,(如何获取请参考:微信公众平台 获取access_token)。其次是模板消息的参数封装,最后就是http的post请求。我的http请求是使用Spring的restTemplate进行请求,就不用我单独写一个http请求方法,如果没有使用可以写一个http请求的工具类。

(3)封装响应参数Demo

package com.plateno.weixin.message.model;

public class WeixinResponse {
  private String msgid;
  private int errcode;
  private String errmsg;

  public String getMsgid() {
    return msgid;
  }
  public void setMsgid(String msgid) {
    this.msgid = msgid;
  }
  public int getErrcode() {
    return errcode;
  }
  public void setErrcode(int errcode) {
    this.errcode = errcode;
  }
  public String getErrmsg() {
    return errmsg;
  }
  public void setErrmsg(String errmsg) {
    this.errmsg = errmsg;
  }

  @Override
  public String toString() {
    StringBuffer buf = new StringBuffer("WeixinResponse[msgid=");
    buf.append(msgid)
    .append(",errcode=").append(errcode)
    .append(",errmsg=").append(errmsg)
    .append("]");
    return buf.toString();
  }

}

模板消息发送效果:

微信公众平台 发送模板消息(Java接口开发)

四、事件推送

在模版消息发送任务完成后,微信服务器会将是否送达成功作为通知,发送到开发者中心中填写的服务器配置地址中。

1 送达成功时

(1)推送的XML如下

 <xml>
      <ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
      <FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]></FromUserName>
      <CreateTime>1395658920</CreateTime>
      <MsgType><![CDATA[event]]></MsgType>
      <Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
      <MsgID>200163836</MsgID>
      <Status><![CDATA[success]]></Status>
      </xml>

(2)参数说明

参数 说明
ToUserName 公众号微信号
FromUserName 接收模板消息的用户的openid
CreateTime 创建时间
MsgType 消息类型是事件
Event 事件为模板消息发送结束
MsgID 消息id
Status 发送状态为成功

 2 送达由于用户拒收(用户设置拒绝接收公众号消息)而失败时

(1)推送的XML如下

  <xml>
      <ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
      <FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]></FromUserName>
      <CreateTime>1395658984</CreateTime>
      <MsgType><![CDATA[event]]></MsgType>
      <Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
      <MsgID>200163840</MsgID>
      <Status><![CDATA[failed:user block]]></Status>
      </xml>

(2)参数说明

参数 说明
ToUserName 公众号微信号
FromUserName 接收模板消息的用户的openid
CreateTime 创建时间
MsgType 消息类型是事件
Event 事件为模板消息发送结束
MsgID 消息id
Status 发送状态为用户拒绝接收

3 送达由于其他原因失败时

(1)推送的XML如下

 <xml>
      <ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
      <FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]></FromUserName>
      <CreateTime>1395658984</CreateTime>
      <MsgType><![CDATA[event]]></MsgType>
      <Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
      <MsgID>200163840</MsgID>
      <Status><![CDATA[failed: system failed]]></Status>
      </xml>

(2)参数说明

参数 说明
ToUserName 公众号微信号
FromUserName 接收模板消息的用户的openid
CreateTime 创建时间
MsgType 消息类型是事件
Event 事件为模板消息发送结束
MsgID 消息id
Status 发送状态为发送失败(非用户拒绝)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。

以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

您可能感兴趣的文章:

  • java实现微信企业付款到个人账户方法
  • java微信小程序开发中加密解密算法总结
  • Java微信分享接口开发 相关电子书
    学习笔记
    网友NO.320209

    java实现微信公众号发送模版消息

    前言: 在我们购买商品或其他操作的时候,这时候微信公众号会推送相关模版消息。接下来简单介绍开发流程:(本文以订单推送为例) 首先在测试号新建模版消息 格式如下: {{first.DATA}} 用户名:{{keyword1.DATA}} 订单号:{{keyword2.DATA}} 订单金额:{{keyword3.DATA}} 商品信息:{{keyword4.DATA}} {{remark.DATA}} 这里会生成一个模版ID,后面会用到 然后后台在上传订单接口,上传成功后调用发送模版消息,代码实现: public void sendOrderTemplateMessage(Order order) { AugeWechatUser wechatUser = augeWechatUserMapper.selectByPhone(order.getPhone()); String goodsInfo = ""; for (AugeSaleItem augeSaleItem : order.getData()) { goodsInfo += augeSaleItem.getItemName() + "×" + augeSaleItem.getItemNum() + "\n\t\t\t"; } DataInfo first = new DataInfo("恭喜你购买成功!", "#ff0000"); DataInfo keyword1 = new DataInfo(wechatUser.getNickName(), "#ff0000"); DataInfo keyword2 = new D……

    网友NO.706804

    微信小程序实现获取小程序码和二维码java接口开发

    前言:目前小程序推出了自己的识别码,小程序码,这个圆形的码看起来比二维码好看。本文总结微信小程序的获取小程序码和二维码并生成二维码图片的接口开发。主要内容摘抄自微信小程序的API文档,java接口开发是自己总结开发。 微信小程序API文档:获取二维码 一、简介 通过后台接口可以获取小程序任意页面的二维码,扫描该二维码可以直接进入小程序对应的页面。目前微信支持两种二维码,小程序码(左),小程序二维码(右),如下所示: 二、获取小程序码 目前有两个接口可以生成小程序码,开发者可以根据自己的需要选择合适的接口。 1 不带参数有限个数小程序码接口 适用于需要的码数量较少的业务场景 接口地址: https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN 注:获取accesstoken的方法跟微信公众获取accesstoken方法一致,不过小程……

    网友NO.478878

    JavaScript实现微信号随机切换代码

    js实现微信号随机切换,代码分为js和html部分,大家参考下 js代码: arr_wx =new Array("aaaa","bbbb","cccc"); var wx_index = Math.floor((Math.random() * arr_wx.length)); var stxlwx = arr_wx[wx_index]; var img = "?php echo $pctem['pathurl'] ?"+arr_wx[wx_index]+".jpg" html代码: scriptdocument.write(stxlwx)/script 总结 以上所述是小编给大家介绍的JavaScript实现微信号随机切换代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对码农之家网站的支持! ……

    网友NO.581396

    Java微信支付之关闭订单

    本文实例为大家分享了java微信支付之关闭订单的具体代码,供大家参考,具体内容如下 官方文档 一、应用场景 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付 系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口 注意: 订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟。 二、接口地址 https://api.mch.weixin.qq.com/pay/closeorder 三、请求参数 只能根据自己商户系统的订单号关闭 package com.phil.wechatpay.model.rep; import java.io.Serializable; /** * 关闭订单请求参数(正常XML) * @author phil * @date 2017年7月25日 * */ public class CloseOrderParams extends AbstractPayParams implements Serializable{ /** * */ private static final long serialVersionUID = -4206464928803827244L; private String out_trade_no; //商户订单号 public String getOut_trade_no() { retu……

    网友NO.844307

    微信跳一跳辅助Java代码实现

    微信跳一跳辅助的Java具体实现代码,供大家参考,具体内容如下 1.参考知乎教你用Python来玩微信跳一跳,鉴于本人Python一直都是半吊子水平,之前打算用python刷分,可无奈安装python环境各种模块缺失,报错不停,于是乎,使用Java重新实现了一下。 2.环境配置及相关说明: 1)、Windows系统,本人win10 2)、AVA环境安装,JDK7以上即可 3)、安卓手机一部、数据线一条 4)、电脑安装ADB驱动,连接安卓手机,同时打开USB调试模式 5)、打开微信小程序的跳一跳游戏,JAVA程序跑起来,具体代码往下看 6)、本人所用为魅蓝note2安卓手机,屏幕 分辨率1920x1080,不同型号的手机,可能需要调整相关参数,具体看代码注释 7)、增加了刷分失败后游戏自动重新开局功能 8)、娱乐而已,不要较真,据说微信官方已经关注,分数太高可能会被清零,哈哈 3、废话不多说,……

    <
    1
    >

    Copyright 2018-2020 www.xz577.com 码农之家

    版权投诉 / 书籍推广 / 赞助:520161757@qq.com