根据配置的URL,微信第一次验证请求发送GET请求,之后发送的消息都是发送POST请求到该URL上,我们看看之前写的post方法
/**
* 消息的处理和响应
* @param request
* @param response
* @throws Exception
*/
@RequestMapping(value="handle",method=RequestMethod.POST)
public void messageHandle(HttpServletRequest request,HttpServletResponse response) throws Exception{
}
request中封装了微信发送过来的所有信息,
response用来对微信服务器进行响应。
一:准备需要的jar包或依赖
服务器解析微信发过来的xml数据需要用到 -- 开源框架dom4j
jar包下载地址:http://www.dom4j.org/dom4j-1.6.1/
maven依赖:
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6</version>
</dependency>
服务器响应微信时将内容转为xml格式数据需要使用到 -- 开源框架xstream
maven依赖:
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.7</version>
</dependency>
二:封装一个消息处理类,提供方法用来获取requst中内容,装入map,将回复的内容转为xml格式的数据
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.mote.weixin.entry.Response_Text;
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 MessageUtils {
// 请求消息类型:文本
public static final String REQ_MESSAGE_TYPE_TEXT = "text";
// 请求消息类型:图片
public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
// 请求消息类型:语音
public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
// 请求消息类型:视频
public static final String REQ_MESSAGE_TYPE_VIDEO = "video";
// 请求消息类型:小视频
public static final String REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo";
// 请求消息类型:地理位置
public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
// 请求消息类型:链接
public static final String REQ_MESSAGE_TYPE_LINK = "link";
// 请求消息类型:事件推送
public static final String REQ_MESSAGE_TYPE_EVENT = "event";
// 事件类型:subscribe(订阅)
public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
// 事件类型:unsubscribe(取消订阅)
public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
// 事件类型:scan(用户已关注时的扫描带参数二维码)
public static final String EVENT_TYPE_SCAN = "scan";
// 事件类型:LOCATION(上报地理位置)
public static final String EVENT_TYPE_LOCATION = "LOCATION";
// 事件类型:CLICK(自定义菜单)
public static final String EVENT_TYPE_CLICK = "CLICK";
// 响应消息类型:文本
public static final String RESP_MESSAGE_TYPE_TEXT = "text";
// 响应消息类型:图片
public static final String RESP_MESSAGE_TYPE_IMAGE = "image";
// 响应消息类型:语音
public static final String RESP_MESSAGE_TYPE_VOICE = "voice";
// 响应消息类型:视频
public static final String RESP_MESSAGE_TYPE_VIDEO = "video";
// 响应消息类型:音乐
public static final String RESP_MESSAGE_TYPE_MUSIC = "music";
// 响应消息类型:图文
public static final String RESP_MESSAGE_TYPE_NEWS = "news";
/**
* 解析微信发来的请求(XML)封装成map
*
* @param request
* @return Map<String, String>
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
// 将解析结果存储在HashMap中
Map<String, String> map = new HashMap<String, String>();
// 从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;
}
/**
* 扩展xstream使其支持CDATA
*/
private static XStream xstream = new XStream(new XppDriver() {
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
// 对所有xml节点的转换都增加CDATA标记
boolean cdata = true;
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(RespMessage_Text responseText) {
xstream.alias("xml", responseText.getClass());
return xstream.toXML(responseText);
}
}
三:写一个CoreService来完成主要业务
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.mote.weixin.entry.Response_Text;
import com.mote.weixin.utils.MessageUtils;
public class CoreService {
public static String processRequest(HttpServletRequest request)
throws Exception {
// 返回的xml数据
String resqXml = null;
// 返回的文本内容
String resqContext = null;
// 将request交给消息处理类
Map<String, String> map = MessageUtils.parseXml(request);
// 获取消息类型
String msgType = map.get("MsgType");
// 封装返回消息
RespMessage_Text responseText = new RespMessage_Text();
responseText.setFromUserName(map.get("ToUserName"));
responseText.setToUserName(map.get("FromUserName"));
responseText.setCreateTime(new Date().getTime());
// 根据不同消息类型做出相应的处理
// 文本消息
if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_TEXT)) {
resqContext = "您发送了文本消息";
}
// 图片消息
if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_IMAGE)) {
resqContext = "您发送了图片消息";
}
//事件消息
if (msgType.equals(MessageUtils.REQ_MESSAGE_TYPE_EVENT)) {
//获取事件类型
String eventType = map.get("EVENT");
if(eventType.equals(MessageUtils.EVENT_TYPE_SUBSCRIBE)){
//关注
resqContext = "谢谢你的关注";
}
if(eventType.equals(MessageUtils.EVENT_TYPE_UNSUBSCRIBE)){
//TODO取消关注
}
if(eventType.equals(MessageUtils.EVENT_TYPE_CLICK)){
//TODO自定义菜单
}
if(eventType.equals(MessageUtils.EVENT_TYPE_SCAN)){
//TODO扫描二维码
}
}
//设置返回内容
responseText.setContent(resqContext);
//将对象转为xml数据
resqXml = MessageUtils.messageToXml(responseText);
return resqXml;
}
}
四:在post方法中调用CoreService处理业务
/**
* 消息的处理和响应
* @param request
* @param response
* @throws Exception
*/
@RequestMapping(value="handle",method=RequestMethod.POST)
public void messageHandle(HttpServletRequest request,HttpServletResponse response) throws Exception{
//将请求、响应的编码设置为utf-8
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
//调用核心业务逻辑
String respXml = CoreService.processRequest(request);
//响应消息
PrintWriter out = response.getWriter();
out.print(respXml);
out.close();
}