微信大众号开发之接收消息
微信公众号开发之接收消息
1、注册微信公众订阅号
2、服务器配置:
URL(服务器地址):rest/portal/getWeixinTokenToken
(令牌):XXX
EncodingAESKey(消息加解密密钥):VzfRmFPyc7BNm84OzNHIY5EwfTkbGmgodF58OW0ZouW
消息加解密方式:明文模式
3、微信公众号发送消息到服务器首先会访问get方法验证token,然后访问post方法将消息推送到服务器
URL:用Java编写,部署到服务器
第一步,访问get方法,验证token
import java.io.IOException; import java.io.PrintWriter; @Path("/getWeixinToken") @GET @Description("微信token验证") public void listSchoolHotMessageByPage(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { String signature = request.getParameter("signature"); // 时间戳 String timestamp = request.getParameter("timestamp"); // 随机数 String nonce = request.getParameter("nonce"); // 随机字符串 String echostr = request.getParameter("echostr"); PrintWriter out = response.getWriter(); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (WeiXinSignUtil.checkSignature(signature, timestamp, nonce)) { out.print(echostr); } out.close(); out = null; }
package com.mashang.xlb.modules.portalmanage.util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; public class WeiXinSignUtil { // 与接口配置信息中的Token要一致 private static String token = "weixinCourse"; /** * 验证签名 * * @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); StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } 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; } }
2、访问post方法,并将消息发送到服务器:
@Path("/getWeixinToken") @POST @Description("微信token验证") @Consumes(MediaType.TEXT_XML) public void getWeixinTokenReceiveMsg(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException, IllegalArgumentException, IllegalAccessException, DOMException { WeiXinReceiveMsgDTO wxrmDto = parseXml(request); LogUtil.debug(log, wxrmDto.toString()); response.getWriter().write("成功!"); } private WeiXinReceiveMsgDTO parseXml(HttpServletRequest request) throws IllegalArgumentException, IllegalAccessException, DOMException{ WeiXinReceiveMsgDTO wxrmDto = new WeiXinReceiveMsgDTO(); try { InputStream is = request.getInputStream(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(is); NodeList employees = document.getChildNodes(); for (int i = 0; i < employees.getLength(); i++) { Node employee = employees.item(i); NodeList employeeInfo = employee.getChildNodes(); for (int j = 0; j < employeeInfo.getLength(); j++) { Node node = employeeInfo.item(j); NodeList employeeMeta = node.getChildNodes(); for (int k = 0; k < employeeMeta.getLength(); k++) { this.setOjectFieldValue(wxrmDto,node.getNodeName(),employeeMeta.item(k).getTextContent()); } } } } catch (IOException | ParserConfigurationException | SAXException e) { e.printStackTrace(); } return wxrmDto; } /** * 给对象的属性赋值 * @param obj 对象 * @param name 需要赋值属性名称 * @param value 需要的赋值 * @throws IllegalArgumentException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws SecurityException */ private void setOjectFieldValue(Object obj, String name , String value){ try { Field[] flds = obj.getClass().getDeclaredFields(); for (int k2 = 0; k2 < flds.length; k2++) { String foeldName = flds[k2].getName().replaceFirst(flds[k2].getName().substring(0, 1), flds[k2].getName().substring(0, 1).toUpperCase()); if(foeldName.equals(name)){ //关键。。。可访问私有变量 flds[k2].setAccessible(true); //对属性赋值 flds[k2].set(obj, value); } } } catch (IllegalArgumentException | IllegalAccessException e) { e.printStackTrace(); } }