微信开发 一 接入篇
来源:互联网 发布:明源软件怎么样 编辑:程序博客网 时间:2024/06/17 04:53
本例中有些引用的类与方法不做过多介绍,之后会提供完整源码下载,请自行查看。
本篇根据开发者文档-接入指南编写。请对照查看,一些传入与返回参数就不过多介绍。地址为:https://mp.weixin.qq.com/wiki/17/2d4265491f12608cd170a95559800f2d.html
服务器配置
获取开发者信息
在项目中配置信息
服务器配置信息
![]()
Token : 必须与代码中配置相同,如本处都为: wechat。
EncodingAESKey : 必须与代码中配置相同。
注意:微信公众服务地址必须以http://或https://开头,分别支持80端口和443端口。微信公众号接口只支持80接口。而Linux 80端口被系统默认。所以必须将80端口请求重定向到8080。具体配置如下:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
验证服务器地址的有效性
编写服务器主路径
该路径与服务器配置信息中URL中配置路径相同。GET请求携带四个参数:
参数 描述 signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 timestamp 时间戳 nonce 随机数 echostr 随机字符串
@Controller@RequestMapping("/core")public class WeChatCoreController { private static final Logger logger = Logger.getLogger(WeChatCoreController.class); @Resource private WeChatCoreService weChatCoreService; @RequestMapping("/start") public void start(HttpServletRequest request, HttpServletResponse response) { logger.info("===========startWeChat============"); try { // 将请求、响应的编码均设置为UTF-8(防止中文乱码) request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); String method = request.getMethod(); if(method.equals("GET")) { String signature = request.getParameter("signature"); // 微信加密签名 String timestamp = request.getParameter("timestamp"); // 时间戳 String nonce = request.getParameter("nonce"); // 随机数 String echostr = request.getParameter("echostr"); // 随机字符串 System.out.println("确认配置>>>>>>>>>signature="+signature+" ,timestamp="+timestamp); if(signature != null && timestamp != null) { // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (weChatCoreService.checkSignature(signature, timestamp, nonce)) { out.print(echostr); } } } else if(method.equals("POST")) { System.out.println("=================New Message=================="); String respMessage = weChatCoreService.processRequest(request); out.print(respMessage); } out.close(); } catch (Exception e) { e.printStackTrace(); } }}
验证有效性
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
加密/校验流程如下:
1. 将token、timestamp、nonce三个参数进行字典序排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密
3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
public boolean checkSignature(String signature, String timestamp, String nonce) { logger.info("==========checkSignature=========="); String[] arr = new String[] { WeChatCertificate.WECHAT_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 = StringUtil.byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } content = null; // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; }
业务逻辑
此后用户每次向公众号发送消息、或者产生自定义菜单点击事件时,开发者填写的服务器配置URL将得到微信服务器推送过来的消息和事件,然后开发者可以依据自身业务逻辑进行响应,例如回复消息等。
用户向公众号发送消息时,公众号方收到的消息发送者是一个OpenID,是使用用户微信号加密后的结果,每个用户对每个公众号有一个唯一的OpenID。
本方法中有些调用类与方法将之后章节中介绍说明
/** * 处理用户发送的消息 */ public String processRequest(HttpServletRequest request) { logger.info("==========processRequest=========="); String respMessage = null; try { Map< String, String> requestMap = new HashMap< String, String>(); //安全模式,消息包为纯密文,需要开发者加密和解密,安全系数高 注:java.security.InvalidKeyException:illegal Key Size 请参考Remark文件 第二条 WXBizMsgCrypt pc = new WXBizMsgCrypt(WeChatCertificate.WECHAT_TOKEN, WeChatCertificate.WECHAT_ENCODINGAESKEY, WeChatCertificate.WECHAT_APPID); String encrypt_type =request.getParameter("encrypt_type"); if (encrypt_type == null || encrypt_type.equals("raw")) { //不用加密 requestMap = XMLUtil.parseXml(request); // xml请求解析 } else { //需走加解密流程 String msgSignature = request.getParameter("msg_signature");// 微信加密签名 String timeStamp = request.getParameter("timestamp"); // 时间戳 String nonce = request.getParameter("nonce"); // 随机数 String encryptMsg = StringUtil.inputStream2String(request.getInputStream()); //密文 String data = pc.decryptMsg(msgSignature, timeStamp, nonce, encryptMsg); requestMap = XMLUtil.parseXml(data); // xml请求解析 } String msgType = requestMap.get("MsgType"); // 消息类型 String xmlStr = requestMap.get("wechatXML"); // 用户传来的xml System.out.println("Receive information>>>"+xmlStr); logger.info("Receive information:>>>"+xmlStr); switch(msgType) { case WeChatEntitiesType.REQ_MESSAGE_TYPE_IMAGE : respMessage = ImageRespMsg.test(xmlStr); break; case WeChatEntitiesType.REQ_MESSAGE_TYPE_VOICE : respMessage = VoiceRespMsg.test(xmlStr); break; case WeChatEntitiesType.REQ_MESSAGE_TYPE_VIDEO : respMessage = VideoRespMsg.test(xmlStr); break; case WeChatEntitiesType.REQ_MESSAGE_TYPE_SHORTVIDEO : respMessage = VideoRespMsg.test(xmlStr); break; case WeChatEntitiesType.REQ_MESSAGE_TYPE_LINK : respMessage = TextRespMsg.test(xmlStr); break; case WeChatEntitiesType.REQ_MESSAGE_TYPE_LOCATION : respMessage = TextRespMsg.test(xmlStr); break; case WeChatEntitiesType.REQ_MESSAGE_TYPE_TEXT : { String content = requestMap.get("Content"); switch(content) { case "news" : respMessage = NewsRespMsg.test(xmlStr); break; case "music" : respMessage = MusicRespMsg.test(xmlStr); break; default : respMessage = TextRespMsg.test(xmlStr); } } break; case WeChatEntitiesType.REQ_MESSAGE_TYPE_EVENT : { String event = requestMap.get("Event"); String wechatXML = requestMap.get("wechatXML"); switch(event) { case WeChatEntitiesType.EVENT_TYPE_CLICK : MenuClickEvent.requestMessage(wechatXML); break; case WeChatEntitiesType.EVENT_TYPE_VIEW : MenuViewEvent.requestMessage(wechatXML); } respMessage = TextRespMsg.test(xmlStr); } break; default : respMessage = TextRespMsg.test(xmlStr); } //对返回消息进行加密。注:微信测试号不支持加密模式。测试需注释加解密过程// respMessage = pc.encryptMsg(respMessage, System.currentTimeMillis()+"", "xxxxxx"); System.out.println("returned messages>>>"+respMessage); logger.info("returned messages:>>>"+respMessage); } catch(Exception e) { e.printStackTrace(); } return respMessage; }
- 微信开发 一 接入篇
- 微信学习开发笔记:一、微信的接入
- 微信开发接入
- 微信开发-接入
- 微信开发(一)公众号接入服务器
- dotNet微信公众号开发一:接入
- java微信开发API解析(一)-服务器接入
- java微信开发API解析(一)-服务器接入
- 微信公众号开发一:接入指南
- 微信公众号开发一(接入配置)
- 微信开发 接入参数
- 微信开发【基本接入】
- 微信接入自定义开发
- 微信开发接入代码
- 微信开发:接入微信入口
- Java微信公众平台开发(一)——接入微信公众平台
- java 微信公众号开发(一)--微信公众号接入
- Java微信公众平台开发(一)--接入微信公众平台
- 3.《MySQL必知必会》函数与汇总
- 翻煎饼问题(代码及解析)
- Spring集成Redis步骤
- PAT乙级(Basic Level)练习题 >分解因数
- 例题6-13 古代象形符号 UVa1103
- 微信开发 一 接入篇
- Codeforces Round #410 (Div. 2) C. Mike and gcd problem 贪心
- Tomcat项目部署shell脚本
- 批处理 自动关闭若干进程,以备关机
- ubuntu 更改wifi的mac地址
- 【IMWeb训练营作业】
- [IMWeb训练营作业]vue实现自定义select下拉框组件
- Activity生命周期順序
- 【IMWeb训练营作业】Select