启用开发者模式后,我们的后台便有了和公众号更多的交互的能力,公众号会向我们的后台推送用户的消息、后台拿到用户的消息后,可以实现类似查询天气、关键字回复、聊天之类的等等有趣的功能。
开发者模式在哪里开启呢?
我们需要配置三个值:服务器地址(接收消息的地址)、自定义token、消息加密方式(可选择明文或者密文),暂时地址只支持80端口,其他端口接收不到消息哦。
在开发者首次提交验证申请时,微信服务器将发送GET请求到填写的URL上,并且带上四个参数signature、timestamp、nonce、echostr(开发者配置的token与timestamp与nonce字典排序后进行sha1加密后的字符串签名、时间戳、随机数、随机字符串),开发者通过对签名(即signature)的效验,来判断此条消息的真实性。此后,每次开发者接收用户消息的时候,微信也都会带上这四个参数访问开发者设置的URL,开发者依然通过对签名的效验判断此条消息的真实性。效验方式与首次提交验证申请一致。
get请求校验请求是否来自微信的方法是:
1. 将token、timestamp、nonce三个参数进行字典排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密
3. 开发者获得加密后的字符串可与signature对比,若相等,原样返回echostr给微信,若不等,此次请求非微信请求,什么也不做。
后台代码:
/**
* 接收及回复微信消息
*
* @param token
* @param signature
* @param timestamp
* @param nonce
* @param echostr
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
@RequestMapping("ansy/weixinMessage")
@ResponseBody
public Callable<Object> weixinMessage(String token, String signature, String timestamp, String nonce,
String echostr, HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
return new Callable<Object>() {
OutData out = new OutData();
public Object call() throws Exception {
if (request.getMethod().toLowerCase().equals("get")) {
doGet(signature, timestamp, nonce, echostr, response);
} else {
doPost(request, response);
}
out.setCode(1);
out.setData(null);
out.setMsg("success");
return out;
}
};
}
/**
* get方式验证token
*/
public void doGet(String signature, String timestamp, String nonce, String echostr, HttpServletResponse response) {
//第一个值是服务器配置的token,我们自定义的,和微信的access_token无关
String[] ArrTmp = { "liboyi921216liboyisdfsdfsdfsdf", timestamp, nonce };
Arrays.sort(ArrTmp);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < ArrTmp.length; i++) {
sb.append(ArrTmp[i]);
}
String pwd = WeixinMessageDigestUtil.getInstance().encipher(sb.toString());
if (pwd.equals(signature)) {
if (!"".equals(echostr) && echostr != null) {
try {
PrintWriter writer = response.getWriter();
writer.print(echostr);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 处理微信服务器发来的消息
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 将请求、响应的编码均设置为UTF-8(防止中文乱码)
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
// 调用核心业务类接收消息、处理消息
String respMessage = coreService.processRequest(request);
// 响应消息
PrintWriter out = response.getWriter();
out.print(respMessage);
out.flush();
out.close();
}
注:开启开发者模式后,自动回复消息和自定义菜单会失效。此时菜单需要通过自定义菜单接口去创建,回复消息也只能后台程序里回复。