用Java搭建微信公众号(一)构建基础请求框架

来源:互联网 发布:淘宝店在哪进货 编辑:程序博客网 时间:2024/05/16 19:34

最近帮朋友搭建一个微信公众号,通过查看微信公众号的开发者手册把基本功能实现了。把一些基本的可以通用的代码贴出来。

微信公众号提供了两种模式,一种是直接编辑模式,通过操作页面就能搭建基本的功能,比如自定义菜单功能就很好用。一种是开发者模式,需要写代码来搭建,基于HTTP接口(不完全符合REST风格)。比较麻烦的是两种模式是二选一的关系,使用了开发者模式,就得丢弃一些直接编辑的方便。

使用开发者模式的第一步是配置服务器。配置了URL,Token之后,微信服务器会发送一个HTTP GET请求到URL,并附加了signature,timestamp, nonce,echostr这几个参数。只要把echostr原样返回,微信服务器就认为配置成功了。而自己的服务器通过下列规则来判断是否配置成功

1. 把timestamp, nonce, token三个参数排序,然后拼成一个字符串

2. 使用SHA1加密这个字符串

3. 如果加密后的字符串等于signature,那么自己的服务器就可以认为配置成功。


配置的URL对应的控制器相当于一个前端控制器,负责处理微信服务器转发过来的请求。这里注意access_token的作用,如果自己的代码访问微信的HTTP接口,需要在HTTP请求中加入access_token。如果是微信服务器转发过来的请求,那么和access_token没有关系,可以直接处理。微信服务器转发过来的请求就两种,一种是GET,一般只在配置服务器的时候会有。另一种是POST XML的请求,比如用户点击微信公众的菜单,用户在微信公众号中发送的请求等等。


基本的处理微信服务器转发过来的请求代码框架如下


import java.io.InputStream;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.Map;import javax.servlet.ServletInputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.springframework.web.servlet.ModelAndView;import org.w3c.dom.Document;public class WeixinAPIController extends AbstractBackController {private static final String token = "1234567890";@Overridepublic ModelAndView handleBackRequest(HttpServletRequest request,HttpServletResponse response, Map model) throws Exception {boolean isGet = request.getMethod().toLowerCase().equals("get");if (isGet) {String echostr = request.getParameter("echostr");StringBuilder weixinContent = new StringBuilder();if (checkSignature(request)) {weixinContent.append(echostr);} else {weixinContent.append("Invalid request");}response.getWriter().print(weixinContent.toString());} else {ServletInputStream in = request.getInputStream();acceptXML(in, response);}response.getWriter().flush();response.getWriter().close();return null;}private void acceptXML(InputStream in, HttpServletResponse response) throws Exception{DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();try {DocumentBuilder builder = factory.newDocumentBuilder();Document doc = builder.parse(in);String toUserName = doc.getElementsByTagName("ToUserName").item(0).getFirstChild().getNodeValue();String fromUserName = doc.getElementsByTagName("FromUserName").item(0).getFirstChild().getNodeValue();String msgType = doc.getElementsByTagName("MsgType").item(0).getFirstChild().getNodeValue();if("text".equals(msgType)){String content = doc.getElementsByTagName("Content").item(0).getFirstChild().getNodeValue();if(content != null && content.length() > 0){             // 接收到微信服务器POST过来的文本信息     // Do something}}else if("event".equals(msgType)){String event = doc.getElementsByTagName("Event").item(0).getFirstChild().getNodeValue();if("CLICK".equals(event)){String commandStr = doc.getElementsByTagName("EventKey").item(0).getFirstChild().getNodeValue();// 接收到微信服务器POST过来的点击菜单信息                                                // Do something}}} catch (Exception e) {e.printStackTrace();}}private boolean checkSignature(HttpServletRequest request) {boolean valid = false;String signature = request.getParameter("signature");String timestamp = request.getParameter("timestamp");String nonce = request.getParameter("nonce");if (signature == null || timestamp == null || nonce == null) {return false;}List<String> array = new ArrayList<String>();array.add(token);array.add(timestamp);array.add(nonce);Collections.sort(array);String tempString = array.get(0) + array.get(1) + array.get(2);MessageDigest sha1;try {sha1 = MessageDigest.getInstance("SHA1");sha1.update(tempString.getBytes());byte[] bytes = sha1.digest();StringBuilder sb = new StringBuilder();for (int i = 0; i < bytes.length; i++) {String shaHex = Integer.toHexString(bytes[i] & 0xFF);if (shaHex.length() < 2) {sb.append(0);}sb.append(shaHex);}String encodedToken = sb.toString();if (encodedToken.equals(signature)) {valid = true;}} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return valid;}}


当启动服务器配置后,需要等待几分钟才会生效。生效之后就可以接收来自微信服务器转发的消息了。



0 0
原创粉丝点击