您的位置:首页 > 移动开发 > 微信开发

微信测试号开发之三 接收处理消息并响应

2017-10-25 13:43 330 查看
根据配置的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();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息