目录结构
- 项目结构图
- 增加相关源代码
- 注册工具类
-
核心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 = git@github.com: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/
输入“测试”,返回“您发送的是文本消息”,如下图所示:
参考文档
完整源代码
相关推荐
微信公众号平台发开书籍与实例文档 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
微信公众平台应用开发实战-完整扫描版 pdf 版本。 微信公众平台应用开发实战-完整扫描版 pdf 文档。 微信公众平台应用开发实战-完整扫描版.pdf 全书一共9章,在逻辑上分为四大部分:第一部分(第1章)介绍了微信公众...
第二部分(第2、3章)介绍了进行微信公众平台开发所需的准备工作及将应用接入微信公众平台的方法;第三部分(第4、5章)详细介绍了微信公众平台已开放的API,通过实战项目对开发框架进行了系统讲解,读者甚至可以...
微信开发实例 微信公众平台开发教程-深入浅出微信公众平台实战开发(微网站、LBS云、Api接口调用、服务号高级接口)1.微信接口前期准备。由北风网提供,微信开发实例微信公众平台基础篇: 1)微信公众平台简介:开发...
刘捷版微信公众平台企业应用开发实战 Sample源码以及相关SDK
本书是微信公众平台应用开发方面的书籍,作者是腾讯公司的软件开发工程师,而且是微信公众平台应用开发的先驱者之一。本书全面介绍了微信公众平台应用开发所需的各项技术,系统解读了微信公众平台开放的API和各项...
对微信公众平台开发有兴趣的同学 对ASP.NET MVC开发有兴趣的同学 有志进入开发行业的所有同学 课程特色: 最前沿ASP.NET MVC 5、Entity Framework 6、微信公众平台5.2 最全6大功能19个接口用法大揭秘 零基础快速...
《微信公众平台应用开发实战》是微信公众平台应用开发领域的经典著作,作者是腾讯公司的资深软件开发工程师,而且是微信公众平台应用开发的先驱者之一。本书全面介绍了微信公众平台应用开发所需的各项技术,系统解读...
《企业微信公众平台开发实战:再小的个体也有自己的品牌》方倍工作室,2015年,配套源码。
ASP.NET MVC 5 微信公众平台整合开发实战第三部
《微信公众平台开发实战》(php版),手打完美书签,方便导航入阅读
微信公众平台应用开发实战-完整扫描版 PDF扫描版,放心下载。
ASP.NET MVC5&微信公众平台整合开发实战(响应式布局、JQuery Mobile,Windows Azure、微信核心开发)完整版30讲视频教程。 适用范围: 对微信公众平台开发有兴趣的同学 对ASP.NET MVC开发有兴趣的同学 有志进入开发...
本书是微信公众平台应用开发领域的经典著作,作者是腾讯公司的资深软件开发工程师,而且是微信公众平台应用开发的先驱者之一。本书全面介绍了微信公众平台应用开发所需的各项技术,系统解读了微信公众平台开放的API...
PHP微信公众平台开发,内容丰富,涵盖了多个PHP微信公众平台开发的方面,适合于初学者来学习借鉴。
微信公众平台开发入门教程
第二部分(第2、3章)介绍了进行微信公众平台开发所需的准备工作及将应用接入微信公众平台的方法;第三部分(第4、5章)详细介绍了微信公众平台已开放的API,通过实战项目对开发框架进行了系统讲解,读者甚至可以...
微信小程序点餐系统微信小程序开发实战项目源码+后台+数据库(毕业设计)微信小程序点餐系统微信小程序开发实战项目源码+后台+数据库(毕业设计)微信小程序点餐系统微信小程序开发实战项目源码+后台+数据库(毕业...