微信公众平台开发实战(02) 响应文本消息
目录结构
- 项目结构图
- 增加相关源代码
- 注册工具类
核心Servlet
- Web工程配置文件
- Maven工程文件
- 上传本地代码到GitHub
- 从GitHub取代码至本地
- 上传工程WAR档至SAE
- 微信客户端测试
- 参考文档
- 完整项目源代码
项目结构图
源代码文件说明
序号 | 文件名 | 说明 | 操作 |
1 | readm.md | 说明文档 | 更新 |
2 | log4j.properties | 日志属性文件 | 新增 |
3 | BaseMessage.java | 消息基类 | 新增 |
4 | TextMessage.java | 文本消息类 | 新增 |
5 | SignUtil.java | 取Token服务类 | 未更新 |
6 | MessageUtil.java | 消息处理工具类 | 新增 |
7 | CoreServlet.java | 核心Servlet,增加doPost()方法 | 更新 |
8 | CoreService.java | 核心服务类,处理前台传过来的请求,并返回响应 | 新增 |
9 | web.xml | Web项目配置文件(这里主要配置Servlet的信息) | 更新 |
10 | index.jsp | 首页文件,显示时间信息,主要用来判断工程是否部署成功 | 未更新 |
增加相关源代码
信息基类
BaseMessage.java
package com.coderdream.model; /** * 请求消息基类(普通用户 -> 公众帐号) * */ public class BaseMessage { /** * 开发者微信号 */ private String ToUserName; /** * 发送方帐号(一个OpenID) */ private String FromUserName; /** * 消息创建时间 (整型) */ private long CreateTime; /** * 消息类型 */ private String MsgType; /** * 消息ID,64位整型 */ private long MsgId; 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 long getMsgId() { return MsgId; } public void setMsgId(long msgId) { MsgId = msgId; } }
文本消息类
TextMessage.java
package com.coderdream.model; /** * 文本消息 */ public class TextMessage extends BaseMessage { /** * 消息内容 */ private String Content; public String getContent() { return Content; } public void setContent(String content) { Content = content; } }
核心服务类
CoreService.java
package com.coderdream.service; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import org.apache.log4j.Logger; import com.coderdream.model.TextMessage; import com.coderdream.util.MessageUtil; /** * 核心服务类 */ public class CoreService { public static String TAG = "CoreService"; private Logger logger = Logger.getLogger(CoreService.class); /** * 处理微信发来的请求 * * @param request * @return xml */ public String processRequest(InputStream inputStream) { Date utilDate = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String str = sdf.format(utilDate); logger.debug(TAG + " ###### log4j debug" + str); logger.info(TAG + " ###### log4j info" + str); logger.trace(TAG + " ###### log4j trace" + str); logger.warn(TAG + " ###### log4j warn" + str); logger.fatal(TAG + " ###### log4j fatal" + str); logger.error(TAG + " ###### log4j error" + str); // xml格式的消息数据 String respXml = null; // 默认返回的文本消息内容 String respContent = "未知的消息类型!"; try { // 调用parseXml方法解析请求消息 Map<String, String> requestMap = MessageUtil.parseXml(inputStream); // 发送方帐号 String fromUserName = requestMap.get("FromUserName"); // 开发者微信号 String toUserName = requestMap.get("ToUserName"); // 消息类型 String msgType = requestMap.get("MsgType"); // 回复文本消息 TextMessage textMessage = new TextMessage(); textMessage.setToUserName(fromUserName); textMessage.setFromUserName(toUserName); textMessage.setCreateTime(new Date().getTime()); textMessage.setMsgType(MessageUtil.MESSAGE_TYPE_TEXT); // 文本消息 if (msgType.equals(MessageUtil.MESSAGE_TYPE_TEXT)) { respContent = "您发送的是文本消息!"; } logger.debug(TAG + " respContent: " + respContent); // 设置文本消息的内容 textMessage.setContent(respContent); // 将文本消息对象转换成xml respXml = MessageUtil.messageToXml(textMessage); logger.debug(TAG + " respXml: " + respXml); } catch (Exception e) { e.printStackTrace(); } return respXml; } }
核心Servlet
CoreServlet.java
package com.coderdream.servlet; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import com.coderdream.service.CoreService; import com.coderdream.util.SignUtil; /** * 请求处理的核心类 * */ public class CoreServlet extends HttpServlet { public static String TAG = "CoreServlet"; private Logger logger = Logger.getLogger(CoreServlet.class); private static final long serialVersionUID = 4440739483644821986L; /** * 请求校验(确认请求来自微信服务器) */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, 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(); // 请求校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (SignUtil.checkSignature(signature, timestamp, nonce)) { out.print(echostr); } out.close(); out = null; } /** * 请求校验与处理 */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Date utilDate = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String str = sdf.format(utilDate); logger.debug(TAG + " ###### log4j debug" + str); logger.info(TAG + " ###### log4j info" + str); logger.trace(TAG + " ###### log4j trace" + str); logger.warn(TAG + " ###### log4j warn" + str); logger.fatal(TAG + " ###### log4j fatal" + str); logger.error(TAG + " ###### log4j error" + str); // 将请求、响应的编码均设置为UTF-8(防止中文乱码) request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); // 接收参数微信加密签名、 时间戳、随机数 String signature = request.getParameter("signature"); String timestamp = request.getParameter("timestamp"); String nonce = request.getParameter("nonce"); PrintWriter out = response.getWriter(); // 请求校验 if (SignUtil.checkSignature(signature, timestamp, nonce)) { // 从request中取得输入流 InputStream inputStream = request.getInputStream(); CoreService coreService = new CoreService(); // 调用核心服务类接收处理请求 String respXml = coreService.processRequest(inputStream); out.print(respXml); } out.close(); out = null; } }
消息处理工具类
MessageUtil.java
package com.coderdream.util; import java.io.InputStream; import java.io.Writer; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import com.coderdream.model.TextMessage; 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 { public static String TAG = "MessageUtil"; private static Logger logger = Logger.getLogger(MessageUtil.class); // 请求消息类型:文本 public static final String MESSAGE_TYPE_TEXT = "text"; /** * 解析微信发来的请求(XML) * * @param request * @return Map<String, String> * @throws Exception */ @SuppressWarnings("unchecked") public static Map<String, String> parseXml(InputStream inputStream) throws Exception { // 将解析结果存储在HashMap中 Map<String, String> map = new HashMap<String, String>(); logger.debug(TAG + " begin"); // 从request中取得输入流 // InputStream inputStream = request.getInputStream(); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); logger.debug(TAG + " read inputStream"); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) { map.put(e.getName(), e.getText()); logger.debug(TAG + " ###### log4j debug" + e.getName() + " : " + e.getText()); } // 释放资源 inputStream.close(); inputStream = null; return map; } /** * 扩展xstream使其支持CDATA */ private static XStream xstream = new XStream(new XppDriver() { public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { // 对所有xml节点的转换都增加CDATA标记 boolean cdata = true; @SuppressWarnings("rawtypes") 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); } } }; } }); /** * 文本消息对象转换成xml * * @param textMessage * 文本消息对象 * @return xml */ public static String messageToXml(TextMessage textMessage) { xstream.alias("xml", textMessage.getClass()); return xstream.toXML(textMessage); } }
Web工程配置文件
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>weixin</display-name> <servlet> <servlet-name>coreServlet</servlet-name> <servlet-class>com.coderdream.servlet.CoreServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>coreServlet</servlet-name> <url-pattern>/coreServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
Maven工程文件
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.coderdream</groupId> <artifactId>wxquan</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>wxquan Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <!-- 测试的时候用到,打包的时候没有 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!-- 编译的时候用到,打包的时候没有 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.4</version> <scope>provided</scope> </dependency> <!-- 编译的时候用到,打包的时候没有 --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <!-- 日志包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.5</version> </dependency> <!-- 打包的时候剔除 xml-apis-1.0.b2.jar SAE中不支持 --> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> <exclusions> <exclusion> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> </exclusion> </exclusions> </dependency> <!-- 打包的时候剔除 xml-apis-1.0.b2.jar SAE中不支持 --> <!-- 这个jar必须用1.4.7的高版本,否则SAE不支持 --> <!-- 详细原因:http://blog.csdn.net/lyq8479/article/details/38878543 --> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.7</version> </dependency> </dependencies> <build> <finalName>wxquan</finalName> </build> </project>
上传本地代码到GitHub
将新增和修改过的代码上传到GitHub
提交成功后,刷新浏览器,查询GitHub中的项目信息:
从GitHub取代码至本地
先在eclipse中设置Git,Windows -> Preferences ->Team -> Git -> Configuration -> Repository Settings,点击“Open”按钮,打开config文件,按如下内容更新:
[core] repositoryformatversion = 0 filemode = false logallrefupdates = true [branch "master"] remote = origin merge = refs/heads/master [remote "origin"] url = [email protected]:CoderDream/wxquan.git fetch = +refs/heads/*:refs/remotes/origin/* push = refs/heads/master:refs/heads/master
更新后的效果如下:
从GitHub上取文件:选择工程,点击右键,Team -> Pull:
弹出如下界面,说明本地和GitHub库有差异,即GitHub库中新增了README.md文件,点击“OK”按钮即可下载到本地。
上传工程WAR档至SAE
将eclipse中的工程导出为wxquan.war档,上传到SAE中,更新已有的版本。
微信客户端测试
登录微信网页版:https://wx.qq.com/
输入“测试”,返回“您发送的是文本消息”,如下图所示:
参考文档
完整源代码
相关推荐
云中舞步 2020-11-12
杨德龙 2020-11-11
JohnYork 2020-10-16
wangzhaotongalex 2020-09-22
xiaoseyihe 2020-11-16
不要皱眉 2020-10-14
Crazyshark 2020-11-13
K先生 2020-11-10
momode 2020-09-11
思君夜未眠 2020-09-04
点滴技术生活 2020-08-21
MaggieRose 2020-08-19
kevinweijc 2020-08-18
wintershii 2020-08-17
vapaad 2020-08-17
wera00 2020-08-17
移动开发与培训 2020-08-16
ReunionIsland 2020-08-16
JimyFengqi 2020-08-16