100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 微信公众号开发--接收与回复消息(Java)

微信公众号开发--接收与回复消息(Java)

时间:2018-07-19 07:19:14

相关推荐

微信公众号开发--接收与回复消息(Java)

分享一下我老师大神的人工智能教程!零基础,通俗易懂!/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

第一步:配置微信公众号

进入微信公众平台地址

进入基本配置

这里需要填写的有服务器的URL、Token两个地方

URL

是一个公网地址,只能接收80端口的(http默认端口)

http://公网地址/项目名称/请求路径

Token

在校验的时候需要用到,随便输入一个字符串就可以了

开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带四个参数

参数 描述

signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。

timestamp 时间戳

nonce 随机数

echostr 随机字符串

所以需要编写相应的Controller(采用springMVC)

/** * 验证微信服务器 * * @param response * @param signature * @param timestamp * @param nonce * @param echostr */ @RequestMapping(value = "/wechat", method = RequestMethod.GET) public void wechatService(PrintWriter out, HttpServletResponse response, @RequestParam(value = "signature", required = false) String signature, @RequestParam String timestamp, @RequestParam String nonce, @RequestParam String echostr) { if (CheckUtil.checkSignature(signature, timestamp, nonce)) { out.print(echostr); } }

12345678910111213141516171234567891011121314151617

CheckUtil.Java

package com.wechat.utils;import java.util.Arrays;/*** * 校验工具类* 开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,* 成为开发者成功,否则接入失败。* * @author GWCheng**/public class CheckUtil {//配置微信公众号时填写的Token private static final String token = "chenggaowei"; public static boolean checkSignature(String signature, String timestamp, String nonce) { // 拼接字符串 String[] arr = new String[] { token, timestamp, nonce }; // 排序 Arrays.sort(arr); // 生成字符串 StringBuffer content = new StringBuffer(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } // SHA1加密 String tmp = DecriptUtil.SHA1(content.toString()); return tmp.equals(signature); }}

12345678910111213141516171819222324252627282930313233341234567891011121314151617181922232425262728293031323334

DecriptUtil.java

import java.io.UnsupportedEncodingException;import java.security.InvalidKeyException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;/*** 各种加密解密**/public class DecriptUtil {public static String SHA1(String decript) { try { MessageDigest digest = java.security.MessageDigest .getInstance("SHA-1"); digest.update(decript.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); // 字节数组转换为 十六进制 数 for (int i = 0; i < messageDigest.length; i++) { String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); if (shaHex.length() < 2) { hexString.append(0); } hexString.append(shaHex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } public static String SHA(String decript) { try { MessageDigest digest = java.security.MessageDigest .getInstance("SHA"); digest.update(decript.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); // 字节数组转换为 十六进制 数 for (int i = 0; i < messageDigest.length; i++) { String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); if (shaHex.length() < 2) { hexString.append(0); } hexString.append(shaHex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } public static String MD5(String input) { try { // 获得MD5摘要算法的 MessageDigest 对象 MessageDigest mdInst = MessageDigest.getInstance("MD5"); // 使用指定的字节更新摘要 mdInst.update(input.getBytes()); // 获得密文 byte[] md = mdInst.digest(); // 把密文转换成十六进制的字符串形式 StringBuffer hexString = new StringBuffer(); // 字节数组转换为 十六进制 数 for (int i = 0; i < md.length; i++) { String shaHex = Integer.toHexString(md[i] & 0xFF); if (shaHex.length() < 2) { hexString.append(0); } hexString.append(shaHex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } /** * 加密 * * @param content * 需要加密的内容 * @param password * 加密密码 * @return */ public static byte[] encryptAES(String content, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 创建密码器 byte[] byteContent = content.getBytes("utf-8"); cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(byteContent); return result; // 加密 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null; } /** * 解密 * * @param content * 待解密内容 * @param password * 解密密钥 * @return */ public static byte[] decryptAES(byte[] content, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 创建密码器 cipher.init(Cipher.DECRYPT_MODE, key);// 初始化 byte[] result = cipher.doFinal(content); return result; // 加密 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null; } /** * BASE64解密 * * @param key * @return * @throws Exception */ public static String decryptBASE64(String key) { return ""; } /** * BASE64加密 * * @param key * @return * @throws Exception */ public static String encryptBASE64(String key) { return ""; }}

12345678910111213141516171819222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119111221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871234567891011121314151617181922232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811911122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187

验证写好了就可以点击提交了

配置成功之后会有如下的提示信息

下面是微信发过来的四个参数,以及给微信回复的echostr

至此开发环境已经配置好了!

第二步:接收消息

环境配置好之后就可以开发了

微信会将发往公众账号的消息发到我们配置的URL中,以POST的方式

​当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

以下是debug的信息

微信已经将发往公众账号的消息发到了我们配置的服务器地址

xml消息不太利于编写程序,所以需要对xml消息进行相应的转换,这里将其转会为map

将xml转换为map

/** * 将xml转化为Map集合 * * @param request * @return */ public static Map<String, String> xmlToMap(HttpServletRequest request) { Map<String, String> map = new HashMap<String, String>(); SAXReader reader = new SAXReader(); InputStream ins = null; try { ins = request.getInputStream(); } catch (IOException e1) { e1.printStackTrace(); } Document doc = null; try { doc = reader.read(ins); } catch (DocumentException e1) { e1.printStackTrace(); } Element root = doc.getRootElement(); @SuppressWarnings("unchecked") List<Element> list = root.elements(); for (Element e : list) { map.put(e.getName(), e.getText()); } try { ins.close(); } catch (IOException e1) { e1.printStackTrace(); } return map; }

12345678910111213141516171819222324252627282930313233341234567891011121314151617181922232425262728293031323334

用到的jar包

dom4j.jar

这个方法写好之后就可以调用了:

Controller如下,微信发过来的消息用POST接收

/** * 接收来自微信发来的消息 * * @param out * @param request * @param response */ @ResponseBody @RequestMapping(value = "/wechat", method = RequestMethod.POST) public void wechatServicePost(PrintWriter out, HttpServletRequest request, HttpServletResponse response) { String responseMessage = wechatService.processRequest(request); out.print(responseMessage); out.flush(); }

12345678910111213141234567891011121314

Controller调用Service的方法(给用户返回消息,也是一个xml格式的字符串)

Service关键代码如下

@Servicepublic class WechatService {private static Logger log = Logger.getLogger(WechatService.class); public String processRequest(HttpServletRequest request) { Map<String, String> map = WechatMessageUtil.xmlToMap(request); log.info(map); // 发送方帐号(一个OpenID) String fromUserName = map.get("FromUserName"); // 开发者微信号 String toUserName = map.get("ToUserName"); // 消息类型 String msgType = map.get("MsgType"); // 默认回复一个"success" String responseMessage = "success"; // 对消息进行处理 if (WechatMessageUtil.MESSAGE_TEXT.equals(msgType)) {// 文本消息 TextMessage textMessage = new TextMessage(); textMessage.setMsgType(WechatMessageUtil.MESSAGE_TEXT); textMessage.setToUserName(fromUserName); textMessage.setFromUserName(toUserName); textMessage.setCreateTime(System.currentTimeMillis()); textMessage.setContent("我已经受到你发来的消息了"); responseMessage = WechatMessageUtil.textMessageToXml(textMessage); } log.info(responseMessage); return responseMessage; }}

12345678910111213141516171819222324252627282930311234567891011121314151617181922232425262728293031

Servie调用WechatMessageUtil将reques中的xml转换为map

WechatMessageUtil.java如下

import java.io.IOException;import java.io.InputStream;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.thoughtworks.xstream.XStream;import com.wechat.entity.vo.wechat.message.TextMessage;public class WechatMessageUtil {// 各种消息类型,除了扫带二维码事件 /** * 文本消息 */ public static final String MESSAGE_TEXT = "text"; /** * 图片消息 */ public static final String MESSAtGE_IMAGE = "image"; /** * 图文消息 */ public static final String MESSAGE_NEWS = "news"; /** * 语音消息 */ public static final String MESSAGE_VOICE = "voice"; /** * 视频消息 */ public static final String MESSAGE_VIDEO = "video"; /** * 小视频消息 */ public static final String MESSAGE_SHORTVIDEO = "shortvideo"; /** * 地理位置消息 */ public static final String MESSAGE_LOCATION = "location"; /** * 链接消息 */ public static final String MESSAGE_LINK = "link"; /** * 事件推送消息 */ public static final String MESSAGE_EVENT = "event"; /** * 事件推送消息中,事件类型,subscribe(订阅) */ public static final String MESSAGE_EVENT_SUBSCRIBE = "subscribe"; /** * 事件推送消息中,事件类型,unsubscribe(取消订阅) */ public static final String MESSAGE_EVENT_UNSUBSCRIBE = "unsubscribe"; /** * 事件推送消息中,上报地理位置事件 */ public static final String MESSAGE_EVENT_LOCATION_UP = "LOCATION"; /** * 事件推送消息中,自定义菜单事件,点击菜单拉取消息时的事件推送 */ public static final String MESSAGE_EVENT_CLICK = "CLICK"; /** * 事件推送消息中,自定义菜单事件,点击菜单跳转链接时的事件推送 */ public static final String MESSAGE_EVENT_VIEW = "VIEW"; /** * 将xml转化为Map集合 * * @param request * @return */ public static Map<String, String> xmlToMap(HttpServletRequest request) { Map<String, String> map = new HashMap<String, String>(); SAXReader reader = new SAXReader(); InputStream ins = null; try { ins = request.getInputStream(); } catch (IOException e1) { e1.printStackTrace(); } Document doc = null; try { doc = reader.read(ins); } catch (DocumentException e1) { e1.printStackTrace(); } Element root = doc.getRootElement(); @SuppressWarnings("unchecked") List<Element> list = root.elements(); for (Element e : list) { map.put(e.getName(), e.getText()); } try { ins.close(); } catch (IOException e1) { e1.printStackTrace(); } return map; } /** * 文本消息转化为xml * * @param textMessage * @return */ public static String textMessageToXml(TextMessage textMessage) { XStream xstream = new XStream(); xstream.alias("xml", textMessage.getClass()); return xstream.toXML(textMessage); }}

12345678910111213141516171819222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119111221231241251261234567891011121314151617181922232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811911122123124125126

用到的jar包有

log4jxstreamxmlpull

用户发来的消息

{MsgId=6241406265466888851, FromUserName=od_Ldw8_rwcGiFsaCeF74Vsc-qz4, CreateTime=1453190638, Content=你好, ToUserName=gh_8f6a0cd44617, MsgType=text}

给用户回复的消息

<xml> <ToUserName>od_Ldw8_rwcGiFsaCeF74Vsc-qz4</ToUserName> <FromUserName>gh_8f6a0cd44617</FromUserName> <CreateTime>1453190640848</CreateTime> <MsgType>text</MsgType> <Content>我已经受到你发来的消息了</Content></xml>

如图所示

完整项目下载地址

/peer44/testwechat

这个地址中的内容在更新,如果觉得有帮助,希望能关注我的动态

参考文献

微信开发者文档

给我老师的人工智能教程打call!/jiangjunshow

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。