启用开发者模式后,我们的后台便有了和公众号更多的交互的能力,公众号会向我们的后台推送用户的消息、后台拿到用户的消息后,可以实现类似查询天气、关键字回复、聊天之类的等等有趣的功能。
开发者模式在哪里开启呢?
我们需要配置三个值:服务器地址(接收消息的地址)、自定义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();
- }
注:开启开发者模式后,自动回复消息和自定义菜单会失效。此时菜单需要通过自定义菜单接口去创建,回复消息也只能后台程序里回复。