微信公众平台开发实战(02) 响应文本消息

目录结构

  • 项目结构图
  • 增加相关源代码
    1. 注册工具类
    2. 核心Servlet

    3. Web工程配置文件
    4. Maven工程文件
  • 上传本地代码到GitHub
  • 从GitHub取代码至本地
  • 上传工程WAR档至SAE
  • 微信客户端测试
  • 参考文档
  • 完整项目源代码

项目结构图

微信公众平台开发实战(02) 响应文本消息
  

源代码文件说明

序号文件名说明操作
1readm.md说明文档更新
2log4j.properties日志属性文件新增
3BaseMessage.java消息基类新增
4TextMessage.java文本消息类新增
5SignUtil.java取Token服务类未更新
6MessageUtil.java消息处理工具类新增
7CoreServlet.java核心Servlet,增加doPost()方法更新
8CoreService.java核心服务类,处理前台传过来的请求,并返回响应新增
9web.xmlWeb项目配置文件(这里主要配置Servlet的信息)更新
10index.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

微信公众平台开发实战(02) 响应文本消息
 

提交成功后,刷新浏览器,查询GitHub中的项目信息:

微信公众平台开发实战(02) 响应文本消息
 

从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

 
 更新后的效果如下:

微信公众平台开发实战(02) 响应文本消息

从GitHub上取文件:选择工程,点击右键,Team -> Pull:

微信公众平台开发实战(02) 响应文本消息
 

弹出如下界面,说明本地和GitHub库有差异,即GitHub库中新增了README.md文件,点击“OK”按钮即可下载到本地。

微信公众平台开发实战(02) 响应文本消息
 

上传工程WAR档至SAE

将eclipse中的工程导出为wxquan.war档,上传到SAE中,更新已有的版本。

微信客户端测试

 登录微信网页版:https://wx.qq.com/

 输入“测试”,返回“您发送的是文本消息”,如下图所示:
微信公众平台开发实战(02) 响应文本消息
 

参考文档

  1. 微信公众帐号开发教程第4篇-消息及消息处理工具的封装
  2. 微信公众帐号开发教程第5篇-各种消息的接收与响应

完整源代码

相关推荐