微信订阅消息需要先向微信申请好消息模板才能发送。
发送之前要想获取微信token。
以上两点本文不包括。
下面是发送消息的后台代码
import java.util.Iterator; import java.util.Map; import java.util.UUID; import javax.annotation.PostConstruct; import javax.annotation.Resource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSONObject; @Component @Lazy(false) public class SubscribeMsgUtil { private static final Log LOG = LogFactory.getLog("SubscribeMsgUtil"); // 发送消息的接口地址 private static final String sendUrl = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="; @Resource(name = "weixinAccessTokenServiceImpl") private WeixinAccessTokenService weixinAccessTokenService; private static SubscribeMsgUtil subscribeMsgUtil; @PostConstruct private void init() { // @Component // @Lazy(false) // @PostConstruct // 这三个注解是为了在util中注入service,本service是为了获取微信token // 如果你采取其他方式获取token,可以不用 subscribeMsgUtil = this; subscribeMsgUtil.weixinAccessTokenService = this.weixinAccessTokenService; } /** * @param openId * 用户openId,不能为空 * @param templateId * 消息模板id,类似 8hRtiCV-wqhbTnppruhQuFUAPvYgY6DBVLNPpayLbbc * @param page * 跳转小程序路径 * @param data * 消息内容,不能为空 * @param state * 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 * @return {"errcode":0,"errmsg":"ok"} */ public static JSONObject sendMsg(String openId, String templateId, String page, JSONObject data, String state) { String uuid = UUID.randomUUID().toString();//用来标识请求编号,用于日志查询 JSONObject resObj = new JSONObject(); LOG.info("(" + uuid + ")sendMsg,入参,openId=" + openId + " templateCode=" + templateCode); // token也可以改成从其他地方传入 String token = subscribeMsgUtil.weixinAccessTokenService.getToken(false); if(DcStringUtils.isNullString(token)) { resObj.put("errcode", "1001"); resObj.put("errmsg", "获取weixinAccessToken失败"); LOG.info("(" + uuid + ")获取weixinAccessToken失败"); return resObj; } String url = sendUrl + token;// 请求路径 // 组装body JSONObject bodyJson = new JSONObject(); bodyJson.put("touser", openId); bodyJson.put("template_id", templateId); if(!DcStringUtils.isNullString(page)) { bodyJson.put("page", page); } // 组装data if(data != null) { JSONObject dataObj = new JSONObject(); Iterator<Map.Entry<String, Object>> iterator = data.entrySet().iterator(); // 把原先的key,value组装成类似形式 // { // "number01": { // "value": "339208499" // } while (iterator.hasNext()) { Map.Entry<String, Object> entry = iterator.next(); JSONObject value = new JSONObject(); value.put("value", entry.getValue()); dataObj.put(entry.getKey(), value); } bodyJson.put("data", dataObj); } bodyJson.put("miniprogram_state", state); String res = HttpClientUtils.doHttpClientPostBody(url, 100, bodyJson); LOG.info("(" + uuid + ")sendMsg,res=" + res); resObj = JSONObject.parseObject(res); return resObj; } }发送请求的方法
/** * * @param url * 请求路径 * @param timeout * 超时时间,单位秒 * @param bodyObj * requestBody * @return */ public static String doHttpClientPostBody(String url, int timeout, JSONObject bodyObj) { String responseBody = "";// 请求返回值 PostMethod method = new UTF8PostMethod(url); try { // 发起请求 HttpClient client = new HttpClient(); HttpConnectionManagerParams managerParams = client.getHttpConnectionManager().getParams(); // 设置连接超时时间(单位毫秒) managerParams.setConnectionTimeout(1000 * timeout); // 设置读数据超时时间(单位毫秒) managerParams.setSoTimeout(1000 * timeout); // 设置请求编码为utf-8 managerParams.setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8"); method.setRequestHeader("Content-Type", "application/json"); RequestEntity se = new StringRequestEntity(bodyObj.toJSONString(), "application/json", "UTF-8"); method.setRequestEntity(se); int statusCode = client.executeMethod(method); if(statusCode != HttpStatus.SC_OK) { Logger.error("statusCode=" + statusCode + url); } else { responseBody = method.getResponseBodyAsString(); if(responseBody!=null&&!responseBody.equals("")) { if("[]".equals(responseBody)) { responseBody = ""; } Logger.info("responseBody=" + responseBody + url); } } } catch (Exception ie) { Logger.error("executeMethod失败=" + ie + url); ie.printStackTrace(); } finally { method.releaseConnection();// 释放连接 } return responseBody; }
小程序前端需要向用户申请权限,由点击事件触发
wx.requestSubscribeMessage({ tmplIds: ['你的tmplId','你的tmplId2'], });