消息回复,实现与用户交互
一、消息接收的数据与回复数据结构分析
1.接收的数据结构
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
2.发送消息的数据结构
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
思路的分析:需要将微信平台发送的xml格式请求信息解析,后台处理已xml的格式返回给微信公众平台;后期的语音消息,图片消息都是类似的思路。
根据xml格式,分析数据结构,构建bean类(做了一个调整,建立一个基类,方便后期的语音,图片的扩展)
/**
*
* 类名称: BaseMessage
* 类描述: 回复消息的基类
* @author yuanjun
* 创建时间:2017年12月8日上午11:38:11
*/
public class BaseMessage {
protected String ToUserName;
protected String FromUserName;
protected long CreateTime;
protected String MsgType;
public BaseMessage() {
super();
}
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;
}
}
/**
*
* 类名称: MessageTest
* 类描述: 消息内容实体
* @author yuanjun
* 创建时间:2017年12月5日上午10:41:40
*/
public class MessageText extends BaseMessage {
private String Content;//文本消息内容
private String MsgId;//消息id,64位整型
public MessageText(){
}
public MessageText(String toUserName, String fromUserName,
long createTime, String msgType, String content, String msgId) {
super();
ToUserName = toUserName;
FromUserName = fromUserName;
CreateTime = createTime;
MsgType = msgType;
Content = content;
MsgId = msgId;
}
public String getContent() {
return Content;
}
public void setContent(String content) {
Content = content;
}
public String getMsgId() {
return MsgId;
}
public void setMsgId(String msgId) {
MsgId = msgId;
}
}二、获取信息请求,封装xml回复信息格式
2.1在pom文件添加dom4j的jar包
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</dependency>
2.2 将后台的xml请求,转成map
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
*
* 类名称: MessageUtil
* 类描述: 消息处理工具
* @author yuanjun
* 创建时间:2017年12月8日下午3:20:48
*/
public class MessageUtil {
/**
* 将微信的请求中参数转成map
* @param request
* @return
*/
public static Map<String,String> xmlToMap(HttpServletRequest request){
Map<String,String> map = new HashMap<String,String>();
SAXReader reader = new SAXReader();
InputStream in = null;
try {
in = request.getInputStream();
Document doc = reader.read(in);
Element root = doc.getRootElement();
List<Element> list = root.elements();
for (Element element : list) {
map.put(element.getName(), element.getText());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return map;
}
}
2.3发送消息的xml封装
/**
*
* 类名称: BaseMessageUtil
* 类描述: 消息封装工具类的基类,这里采用泛型,方便后期功能扩展
* @author yuanjun
* 创建时间:2017年12月6日下午2:06:55
*/
public interface BaseMessageUtil <T>{
/**
* 将回复的信息对象转xml格式给微信
* @param message
* @return
*/
public abstract String messageToxml(T t);
/**
* 回复的信息封装
* @param FromUserName
* @param ToUserName
* @param Content
* @return
*/
public abstract String initMessage(String FromUserName,String ToUserName);
}
2.4实现封装接口,添加xstream,json等jar包
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.9</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
2.5 发送文本消息xml封装实现
public class TextMessageUtil{
/**
* 将发送消息封装成对应的xml格式
*/
public String messageToxml(MessageText message) {
XStream xstream = new XStream();
xstream.alias("xml", message.getClass());
return xstream.toXML(message);
}
/**
* 封装发送消息对象,封装时,需要将调换发送者和接收者的关系
* @param FromUserName
* @param ToUserName
*/
public String initMessage(String FromUserName, String ToUserName) {
MessageText text = new MessageText();
text.setToUserName(FromUserName);
text.setFromUserName(ToUserName);
text.setContent("欢迎关注机械振动工程党支部");
text.setCreateTime(new Date().getTime());
text.setMsgType("text");
return messageToxml.messageToxml(text);
}
}
三、处理post请求,将信息返回到微信平台
3.1 在之前的之前的控制下,添加处理post的方法。
@RequestMapping(value = "wxdemo",method=RequestMethod.POST)
public void dopost(HttpServletRequest request,HttpServletResponse response){
response.setCharacterEncoding("utf-8");
PrintWriter out = null;
//将微信请求xml转为map格式,获取所需的参数
Map<String,String> map = MessageUtil.xmlToMap(request);
String ToUserName = map.get("ToUserName");
String FromUserName = map.get("FromUserName");
String MsgType = map.get("MsgType");
String Content = map.get("Content");
String message = null;
//处理文本类型,实现输入1,回复相应的封装的内容
if("text".equals(MsgType)){
if("1".equals(Content)){
TextMessageUtil textMessage = new TextMessageUtil();
message = textMessage.initMessage(FromUserName, ToUserName);
}
}
try {
out = response.getWriter();
out.write(message);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.close();
}
四、实现与用户的交互,回复用户输入的内容,效果如图
4.1实现代码:重载发送消息的封装,将请求的内容传入,通过post请求发回微信平台
public class TextMessageUtil implements BaseMessageUtil<MessageText> {
//添加封装发送消息的方法,重载,将内容传入
public String initMessage(String FromUserName, String ToUserName,String Content) {
MessageText text = new MessageText();
text.setToUserName(FromUserName);
text.setFromUserName(ToUserName);
text.setContent("您输入的内容是:"+Content);
text.setCreateTime(new Date().getTime());
text.setMsgType("text");
return messageToxml(text);
}
}
4.2 修改post的方法
@RequestMapping(value = "wxdemo",method=RequestMethod.POST)
public void dopost(HttpServletRequest request,HttpServletResponse response){
response.setCharacterEncoding("utf-8");
PrintWriter out = null;
//将微信请求xml转为map格式,获取所需的参数
Map<String,String> map = MessageUtil.xmlToMap(request);
String ToUserName = map.get("ToUserName");
String FromUserName = map.get("FromUserName");
String MsgType = map.get("MsgType");
String Content = map.get("Content");
String message = null;
//处理文本类型,回复用户输入的内容
if("text".equals(MsgType)){
TextMessageUtil textMessage = new TextMessageUtil();
message = textMessage.initMessage(FromUserName, ToUserName,Content);
}
try {
out = response.getWriter();
out.write(message);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.close();
}