【wechat】微信开发——微信验证与处理请求(关注后推送消息)
2015-08-31 18:23
666 查看
1.这里使用的是一个servlet来完成
代码和步骤如下:
代码和步骤如下:
CoreServlet.java
import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import com.raipeng.wechat.domain.TextMessage; import com.raipeng.wechat.util.MessageUtil; @SuppressWarnings("serial") public class CoreServlet extends HttpServlet { private static String token = "weixinCourse"; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub String signature = req.getParameter("signature"); String timestamp = req.getParameter("timestamp"); String nonce = req.getParameter("nonce"); String echostr = req.getParameter("echostr"); PrintWriter pw = resp.getWriter(); if(checkSignature(signature, timestamp, nonce)){ pw.print(echostr); pw.close(); pw = null; } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); String respMessage = null; try { Map<String, String> requestMap = parseXml(req); String toUserName = requestMap.get("ToUserName"); String fromUserName = requestMap.get("FromUserName"); String createTime = requestMap.get("CreateTime"); String msgType = requestMap.get("MsgType"); if(msgType.equals("event")){ String event = requestMap.get("Event"); if(event.equals("subscribe")){ TextMessage textMessage = new TextMessage(); textMessage.setToUserName(fromUserName); textMessage.setFromUserName(toUserName); textMessage.setCreateTime(new Date().getTime()); textMessage.setMsgType("text"); textMessage.setContent("欢迎关注"); respMessage = MessageUtil.textMessageToXml(textMessage); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } PrintWriter writer = resp.getWriter(); writer.print(respMessage); writer.flush(); writer.close(); }
SignUtil.java
/** * 验证签名 * * @param signature * @param timestamp * @param nonce * @return */ public static boolean checkSignature(String signature, String timestamp, String nonce) { String[] arr = new String[] { token, timestamp, nonce }; // 将token、timestamp、nonce三个参数进行字典序排序 //数组排序 Arrays.sort(arr); //String 字符串常量 //StringBuffer 字符串变量(线程安全) //StringBuilder 字符串变量(非线程安全) StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } //java.security.MessageDigest类用于为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。简单点说就是用于生成散列码。 MessageDigest md = null; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 将三个参数字符串拼接成一个字符串进行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } content = null; // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; } /** * 将字节数组转换为十六进制字符串 * * @param byteArray * @return */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * 将字节转换为十六进制字符串 * * @param mByte * @return */ private static String byteToHexStr(byte mByte) { char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } }
MessageUtil.java
/** * 解析微信发来的请求(XML) * * @param request * @return * @throws Exception */ @SuppressWarnings("unchecked") public static Map<String, String> parseXml(HttpServletRequest request) throws Exception { // 将解析结果存储在HashMap中 Map<String, String> map = new HashMap<String, String>(); // 从request中取得输入流 InputStream inputStream = request.getInputStream(); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) map.put(e.getName(), e.getText()); // 释放资源 inputStream.close(); inputStream = null; return map; } /** * 文本消息对象转换成xml * * @param textMessage 文本消息对象 * @return xml */ public static String textMessageToXml(TextMessage textMessage) { xstream.alias("xml", textMessage.getClass()); return xstream.toXML(textMessage); } /** * 扩展xstream,使其支持CDATA块 * * @date 2013-05-19 */ private static XStream xstream = new XStream(new XppDriver() { public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { // 对所有xml节点的转换都增加CDATA标记 boolean cdata = true; @SuppressWarnings("unchecked") public void startNode(String name, Class clazz) { super.startNode(name, clazz); } protected void writeText(QuickWriter writer, String text) { if (cdata) { writer.write("<![CDATA["); writer.write(text); writer.write("]]>"); } else { writer.write(text); } } }; } });
TextMessage.java
private String ToUserName; private String FromUserName; private String MsgType; private long CreateTime; private String Content; public String getToUserName() { return ToUserName; } public void setToUserName(String toUserName) { ToUserName = toUserName; } public String getFromUserName() { return FromUserName; } public void setFromUserName(String fromUserName) { FromUserName = fromUserName; } public String getMsgType() { return MsgType; } public void setMsgType(String msgType) { MsgType = msgType; } public long getCreateTime() { return CreateTime; } public void setCreateTime(long createTime) { CreateTime = createTime; } public String getContent() { return Content; } public void setContent(String content) { Content = content; }
web.xml
<servlet> <servlet-name>coreServlet</servlet-name> <servlet-class>com.raipeng.wechat.servlet.CoreServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>coreServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
相关文章推荐
- 微信二维码生成
- JEECMS的微信插件MessageAct组件冲突
- 微信开发第七篇发送素材(图文)信息
- Android 微信支付
- Android Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- 微信接入
- iOS_微信支付
- 微信分享
- 微信红包API接口(PHP)
- 每天一个小程序——统计字符的个数
- 微信API学习笔记
- 微信 redirect_uri 参数错误
- 使用Chrome修改user agent模拟微信内置浏览器
- 微信公众平台开发(四)——微信支付
- 微信公众平台开发之天气预报功能
- 一款基于微客服的仿微信的聊天软件
- 【微信开发】一获取用户授权(静默授权方式)
- 微信开发大坑汇总之微信支付篇
- 【wechat】微信开发——自定义菜单
- 微信公众平台开发之天气预报功能