微信订阅消息需要先向微信申请好消息模板才能发送。
发送之前要想获取微信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'],
});