0、前提条件

1、需要一个公众平台帐号(测试帐号也可以)
2、平台需要被人关注

1、导入jar

commons-beanutils-1.8.0.jar
commons-collections-3.1.jar
commons-lang-2.5.jar
commons-logging-1.2.jar
date4j.jar
dom4j-1.6.1.jar
dom4j-full.jar
ezmorph-1.0.6.jar
json-lib-2.3-jdk15.jar
jstl.jar
spring-aop-4.1.0.RELEASE.jar
spring-aspects-4.1.0.RELEASE.jar
spring-beans-4.1.0.RELEASE.jar
spring-context-4.1.0.RELEASE.jar
spring-context-support-4.1.0.RELEASE.jar
spring-core-4.1.0.RELEASE.jar
spring-expression-4.1.0.RELEASE.jar
spring-jdbc-4.1.0.RELEASE.jar
spring-tx-4.1.0.RELEASE.jar
spring-web-4.1.0.RELEASE.jar
spring-webmvc-4.1.0.RELEASE.jar
standard.jar
xmlbeans-2.3.0.jar
xmlpull-1.1.3.1.jar
xstream-1.4.7.jar

2、配置springMVC环境

这里不贴代码,具体代码请参考“java微信开发-springMVC配置”。

3、接收消息

处理请求

@Controller
public class HelloWorldController {/*** 微信消息接收和token验证* @param model* @param request* @param response* @throws IOException*/@RequestMapping("/hello")public void hello(Model model, HttpServletRequest request,HttpServletResponse response) throws IOException {boolean isGet = request.getMethod().toLowerCase().equals("get");PrintWriter print;if (isGet) {// 微信加密签名String signature = request.getParameter("signature");// 时间戳String timestamp = request.getParameter("timestamp");// 随机数String nonce = request.getParameter("nonce");// 随机字符串String echostr = request.getParameter("echostr");// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败if (signature != null && CheckoutUtil.checkSignature(signature, timestamp, nonce)) {try {print = response.getWriter();print.write(echostr);print.flush();} catch (IOException e) {e.printStackTrace();}}} else {// 进入post聊天处理System.out.println("enter post");print = response.getWriter();// 接收消息并返回消息// 调用核心服务类接收处理请求String respXml = CoreService.processRequest(request);print.print(respXml);print.flush();print.close();}}
}   

核心服务类

package com.SpringMVC.web.controller;import java.util.Date;
import java.util.Map;import javax.servlet.http.HttpServletRequest;import OAuth2.OAuth;
/*** 核心服务类* * @author 32950745**/
public class CoreService {public static String processRequest(HttpServletRequest request) {// xml格式的消息数据String respXml = null;// 默认返回的文本消息内容String respContent = "未知的消息类型";try {// 调用parseXml方法解析请求消息Map requestMap = MessageUtil.parseXml(request);// 发送方帐号String fromUserName = (String) requestMap.get("FromUserName");// 开发者微信号String toUserName = (String) requestMap.get("ToUserName");// 消息类型String msgType = (String) requestMap.get("MsgType");// 回复文本消息TextMessage textMessage = new TextMessage();textMessage.setToUserName(fromUserName);textMessage.setFromUserName(toUserName);textMessage.setCreateTime(new Date().getTime());textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);// 文本消息if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {respContent = "您发送的是文本消息!";}// 图片消息else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {respContent = "您发送的是图片消息!";}// 语音消息else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {respContent = "您发送的是语音消息!";}// 视频消息else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)) {respContent = "您发送的是视频消息!";}// 地理位置消息else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {respContent = "您发送的是地理位置消息!";}// 链接消息else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {respContent = "您发送的是链接消息!";}// 事件推送else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {// 事件类型String eventType = (String) requestMap.get("Event");// 关注if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {respContent = "谢谢您的关注!";}// 取消关注else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {// TODO 取消订阅后用户不会再收到公众账号发送的消息,因此不需要回复}// 扫描带参数二维码else if (eventType.equals(MessageUtil.EVENT_TYPE_SCAN)) {// TODO 处理扫描带参数二维码事件}// 上报地理位置else if (eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)) {// TODO 处理上报地理位置事件}// 自定义菜单else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {// TODO 处理菜单点击事件}}// 设置文本消息的内容textMessage.setContent(respContent);// 将文本消息对象转换成xmlrespXml = MessageUtil.textMessageToXml(textMessage);return respXml;} catch (Exception e) {e.printStackTrace();}return "";}
}

消息工具类

package com.SpringMVC.web.controller;import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
public class MessageUtil {//APPIDpublic static final String appID = "微信公众平台的appid";//appsecretpublic static final String appsecret = "微信公众平台的apsecred";public static final String RESP_MESSAGE_TYPE_TEXT = "text";public static final Object REQ_MESSAGE_TYPE_TEXT = "text";public static final Object REQ_MESSAGE_TYPE_IMAGE = "image";public static final Object REQ_MESSAGE_TYPE_VOICE = "voice";public static final Object REQ_MESSAGE_TYPE_VIDEO = "video";public static final Object REQ_MESSAGE_TYPE_LOCATION = "location";public static final Object REQ_MESSAGE_TYPE_LINK = "link";public static final Object REQ_MESSAGE_TYPE_EVENT = "event";public static final Object EVENT_TYPE_SUBSCRIBE = "SUBSCRIBE";public static final Object EVENT_TYPE_UNSUBSCRIBE = "UNSUBSCRIBE";public static final Object EVENT_TYPE_SCAN = "SCAN";public static final Object EVENT_TYPE_LOCATION = "LOCATION";public static final Object EVENT_TYPE_CLICK = "CLICK";public static String PREFIX_CDATA = "<![CDATA[";public static String SUFFIX_CDATA = "]]>";/** * 扩展xstream,使其支持CDATA块 * 由于xstream框架本身并不支持CDATA块的生成,下面代码是对xtream做了扩展,* 使其支持在生成xml各元素值时添加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(PREFIX_CDATA);writer.write(text);writer.write(SUFFIX_CDATA);} else {  super.writeText(writer, text);}  }  };  }  });/*** 解析微信发来的请求(xml)* * @param request* @return* @throws Exception*/@SuppressWarnings({ "unchecked", "rawtypes" })public static Map parseXml(HttpServletRequest request) throws Exception {// 将解析结果存储在HashMap中Map map = new HashMap();// 从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());//xstream.processAnnotations(textMessage.getClass());System.out.println(xstream.toXML(textMessage));return xstream.toXML(textMessage);}/*** 音乐消息对象转换成xml* * @param musicMessage*            音乐消息对象* @return xml*/public static String musicMessageToXml(MusicMessage musicMessage) {xstream.alias("xml", musicMessage.getClass());return xstream.toXML(musicMessage);}/*** 图文消息对象转换成xml* * @param newsMessage*            图文消息对象* @return xml*/public static String newsMessageToXml(NewsMessage newsMessage) {xstream.alias("xml", newsMessage.getClass());xstream.alias("item", new Article().getClass());return xstream.toXML(newsMessage);}
}

所有消息基类

package com.SpringMVC.web.controller;import com.thoughtworks.xstream.annotations.XStreamAlias;/*** 消息基类(公众帐号 -> 普通用户)* @author 32950745**/
public class BaseMessage {// 接收方帐号(收到的OpenID)  @XStreamAlias("ToUserName")private String ToUserName;  // 开发者微信号  @XStreamAlias("FromUserName")private String FromUserName;  // 消息创建时间 (整型)  @XStreamAlias("CreateTime")private long CreateTime;  // 消息类型(text/music/news)  @XStreamAlias("MsgType")private String MsgType;  // 位0x0001被标志时,星标刚收到的消息  @XStreamAlias("FuncFlag")private int FuncFlag;  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 long getCreateTime() {  return CreateTime;  }  public void setCreateTime(long createTime) {  CreateTime = createTime;  }  public String getMsgType() {  return MsgType;  }  public void setMsgType(String msgType) {  MsgType = msgType;  }  public int getFuncFlag() {  return FuncFlag;  }  public void setFuncFlag(int funcFlag) {  FuncFlag = funcFlag;  }@Overridepublic String toString() {return "BaseMessage [ToUserName=" + ToUserName + ", FromUserName=" + FromUserName + ", CreateTime=" + CreateTime+ ", MsgType=" + MsgType + ", FuncFlag=" + FuncFlag + "]";}
}

文本消息

package com.SpringMVC.web.controller;import com.thoughtworks.xstream.annotations.XStreamAlias;/*** 消息响应之文本消息:* @author 32950745**/
@XStreamAlias("TextMessage")
//@XStreamAlias("xml")
public class TextMessage extends BaseMessage{// 回复的消息内容  @XStreamAlias("Content")private String Content;  public String getContent() {  return Content;  }  public void setContent(String content) {  Content = content;  }@Overridepublic String toString() {return super.toString()+"\nTextMessage [Content=" + Content + "]";} }

音乐消息

package com.SpringMVC.web.controller;/*** 回复消息之音乐消息* @author 32950745**/@XStreamAlias("MusicMessage ")
public class MusicMessage extends BaseMessage{// 回复的消息内容  private String Content;  @XStreamAlias("Content")public String getContent() {  return Content;  }  public void setContent(String content) {  Content = content;  }
}

图文消息

package com.SpringMVC.web.controller;/*** 回复消息之图文消息* @author 32950745**/
@XStreamAlias("NewsMessage ")
public class NewsMessage extends BaseMessage{// 回复的消息内容  @XStreamAlias("Content")private String Content;  public String getContent() {  return Content;  }  public void setContent(String content) {  Content = content;  }
}
/*** 回复消息之图文消息* @author 32950745**/
@XStreamAlias("Article")
public class Article extends BaseMessage{@XStreamAlias("Title")private String title = "";@XStreamAlias("Description")private String description = "";@XStreamAlias("PicUrl")private String picUrl = "";@XStreamAlias("Url")private String url = "";public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getPicUrl() {return picUrl;}public void setPicUrl(String picUrl) {this.picUrl = picUrl;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}
}

token验证

package com.SpringMVC.web.controller;import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;/*** 请求校验工具类* @author 32950745**/
public class CheckoutUtil {// 与接口配置信息中的Token要一致private static String token = "Javen";/*** 验证签名* * @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);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;}public static void sort(String a[]) {for (int i = 0; i < a.length - 1; i++) {for (int j = i + 1; j < a.length; j++) {if (a[j].compareTo(a[i]) < 0) {String temp = a[i];a[i] = a[j];a[j] = temp;}}}}
}

java微信开发-消息接收和自动回复相关推荐

  1. python实现微信机器人: 登录微信、消息接收、自动回复功能

    这篇文章主要介绍了python实现微信机器人: 登录微信.消息接收.自动回复功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 ...

  2. 微信公众号python人工智能回复_python实现微信机器人: 登录微信、消息接收、自动回复功能...

    安装wxpy pip install -u wxpy 登录微信 # 导入模块 from wxpy import * # 初始化机器人,扫码登陆 bot = bot() 运行以上代码,会生成一个二维码, ...

  3. python实现微信机器人: 登录微信、消息接收、自动回复

    安装wxpy pip install -U wxpy 登录微信 # 导入模块 from wxpy import * # 初始化机器人,扫码登陆 bot = Bot() 运行以上代码,会生成一个二维码, ...

  4. java微信开发API解析(二)-获取消息和回复消息

    java微信开发API解析(二)-获取消息和回复消息 说明 * 本演示样例依据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/20 ...

  5. Java微信开发_00_资源汇总贴

    1.微信公众平台技术文档(https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432) 2.微信企业号开发接口文档(ht ...

  6. java微信开发教程

    微信公众平台开发教程Java版(1)环境准备篇 微信公众平台开发教程Java版(一)环境准备篇 准备写系列博客,记录下我的微信公众平台学习记录,也为那些摸索中的开发者提供点参考. 希望与大家共同进步. ...

  7. Java微信开发入门

    前言: 1.先简单介绍一下微信公众号的开发者模式和编辑模式,玩过微信公众号的同志都知道,在微信公众号后台功能栏里面可以编辑消息自动回复,关键字回复,自定义菜单等功能,这些都是在视图页面下编辑的,叫编辑 ...

  8. java 微信 接收消息_微信公众平台开发教程Java版(三) 消息接收和发送

    https://www.iteye.com/blog/tuposky-2017429 前面两章已经介绍了如何接入微信公众平台,这一章说说消息的接收和发送 可以先了解公众平台的消息api接口(接收消息, ...

  9. java微信开发模板消息接口使用

    微信开发--模板消息接口 http://blog.csdn.net/u010486495/article/details/46985729 微信开发者文档:模板消息接口 模板消息运营规范:http:/ ...

最新文章

  1. 为什么 在内存中为什么 0xffff 是 -1
  2. Activiti部署报错
  3. [转帖]IP地址、子网掩码、网络号、主机号、网络地址、主机地址以及ip段/数字-如192.168.0.1/24是什么意思?...
  4. 一种使用蒸汽眼罩保养的方法
  5. SQL Server查询死锁并KILL
  6. [C/C++]重读《The C Programming Language》
  7. P4336 [SHOI2016]黑暗前的幻想乡
  8. oracle转mysql总结经验,oracle转mysql总结(转)
  9. View Merge 在安全控制上的变化,是 BUG 还是增强 ?
  10. Android数据存储(3):External Storage
  11. Flex动态创建多个曲线图+柱形图
  12. 在sqlexpress中添加DB和在sql analyzer中操作DB.
  13. 洛谷 P2473 [SCOI2008]奖励关 解题报告
  14. C语言程序设计(第三版)何钦铭著 习题3-2
  15. stm32 红外遥控实现
  16. 如何判断一个三位数是否为水仙花数
  17. XCode11中The app delegate must implement the window property if it wants to use 如何解决
  18. linux 实时监控系统IO状态和IO性能
  19. Go 每日一库之 gorilla/mux
  20. 初学者开发iOS游戏的入门必备用书——iOS 5 cocos2d游戏开发实战(第2版)

热门文章

  1. 蒂夫·乔布斯十大经典语录
  2. vue中实现锚点定位
  3. STM32——TIM输入捕获
  4. 初试微信开发--验证token
  5. WPS表格Excel:截取中间内容、截取两符号之间内容
  6. 算法训练Day50 | LeetCode123. 买卖股票的最佳时机III(最多买卖2次);LeetCode188. 买卖股票的最佳时机IV(最多买卖K次)
  7. Node.JS 获取时间戳(毫秒,秒)
  8. Lambda表达式从入门到玩嗨儿~
  9. mysql如何优化联合索引abc使用
  10. 解决谷歌浏览器(chrome)无法访问一些特殊端口地址的问题