04节- 微信公众号消息处理
目录
1.获取消息
- 关注测试号二维码
在测试号管理中就能看到,微信扫码关注即可。
- 发送消息
关注之后,发送消息即可,发送消息servle会收到一个post请求,验证代码如下
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 接收关注的用户发送过来的消息
ServletInputStream is = req.getInputStream();
byte [] b = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while((len=is.read(b))!= -1){
sb.append(new String(b,0,len));
}
System.out.println(sb.toString());
}
- 接收消息内容的格式
<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>
- 调用正常的解析流程
首先对接收到的请求进行解析操作并回复信息
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 首先对接收到的消息和回复的消息进行编码规范
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
//处理消息和事件推送
Map<String,String> reqMap = WxutilService.parseRequest(req.getInputStream());
System.out.println(reqMap);
// 准备回复的数据包
// 这块需要进行优化重写
String respxml ="<xml>\n" +
" <ToUserName><![CDATA["+reqMap.get("FromUserName")+"]]></ToUserName>\n" +
" <FromUserName><![CDATA["+reqMap.get("ToUserName")+"]]></FromUserName>\n" +
" <CreateTime>"+System.currentTimeMillis()/1000 +"</CreateTime>\n" + //这个是秒级所以需要/1000
" <MsgType><![CDATA[text]]></MsgType>\n" +
" <Content><![CDATA[why?]]></Content>\n" +
"</xml>";
// String respxml = WxutilService.getRespose(reqMap);
PrintWriter out = resp.getWriter();
out.write(respxml);
out.flush();
out.close();
}
/**
* 解析xml数据包
* @param is
* @return
*/
public static Map<String, String> parseRequest(ServletInputStream is) {
Map<String,String> map = new HashMap<>();
SAXReader reader = new SAXReader();
try {
// 读取输入流,获取document对象
Document document = reader.read(is);
// 根据document获取根节点信息
Element root = document.getRootElement();
// 获取根节点获取所有的子节点
List<Element> elements = root.elements();
for (Element e:elements) {
map.put(e.getName(),e.getStringValue());
}
}catch (DocumentException e){
e.printStackTrace();
}
return map;
}
需要增加的jar包
<!--xml 解析jar -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
- 优化处理
增加类型处理方案
具体类型请参考微信官方文档
https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html
/**
* 用于处理所有的事件和消息回复
* @param reqMap
* @return
*/
// 这块我就写了一个Text的处理方案
public static String getRespose(Map<String, String> reqMap) {
BaseMessage msg;
String msgType = reqMap.get("MsgType");
switch (msgType){
// 处理文本消息
case "text":
msg = dealTextMessage(reqMap);
break;
case "image":
msg = dealImageMessage(reqMap);
break;
// case "voice":
//
// break;
// case "music":
//
// break;
// case "news":
//
// break;
// default:
// break;
}
return null;
}
package com.wanbo.springbootwx.entity;
import com.thoughtworks.xstream.annotations.XStreamAlias;;
import java.util.Map;
// 基础类信息,所有的处理类型都有
@XStreamAlias("xml") //这个标签是在返回信息的时候通过对象转成xml的方法
public class BaseMessage {
// 发送信息的openid
@XStreamAlias("ToUserName")
public String toUserName;
// 信息来自openid
@XStreamAlias("FromUserName")
public String fromUserName;
// 创建时间
@XStreamAlias("CreateTime")
public String createTime;
//消息类型
@XStreamAlias("MsgType")
public String msgType;
public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}
public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
public BaseMessage(Map<String,String> reqMap){
this.toUserName = reqMap.get("FromUserName");
this.fromUserName = reqMap.get("ToUserName");
this.createTime = System.currentTimeMillis()/1000+"";
}
}
package com.wanbo.springbootwx.entity;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import java.util.Map;
// 个性化的处理方法,不通的类型需要重新构思对象
@XStreamAlias("xml")
public class TextMessage extends BaseMessage {
@XStreamAlias("Content")
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public TextMessage(Map<String,String> reqMap,String content){
super(reqMap);
this.setMsgType("text");
this.content = content;
}
@Override
public String toString() {
return "TextMessage{" +
"content='" + content + '\'' +
", toUserName='" + toUserName + '\'' +
", fromUserName='" + fromUserName + '\'' +
", createTime='" + createTime + '\'' +
", msgType='" + msgType + '\'' +
'}';
}
}
/**
* 处理文本消息
* @param reqMap
* @return
*/
private static BaseMessage dealTextMessage(Map<String, String> reqMap) {
TextMessage tm = new TextMessage(reqMap,"why?");
return tm;
}
- 把对象解析成xml
需要处理的方法我写到了测试类上面
/**
* 该方法验证的是xml文件的组装以及组装xml的时候需要做什么操作
* 如果要修改节点内容的化使用@XStreamAlias进行修改即可
*/
@Test
void textMeg(){
//创建对象(随便写的数据)
Map <String,String> map = new HashMap<String ,String>();
map.put("ToUserName","to");
map.put("FromUserName","from");
map.put("MsgType","type");
TextMessage textMessage = new TextMessage(map,"你好");
XStream stream = new XStream();
stream.processAnnotations(TextMessage.class); //为什么加一个这个就能好
String s = stream.toXML(textMessage);
System.out.println(s);
}
需要引入的jar
<!-- Object 解析成xml-->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>
按照上面的BaseMessage和Text的Message上增加注解。
就能得到真正的xml类型的数据,然后通过
String respxml = WxutilService.getRespose(reqMap);
PrintWriter out = resp.getWriter();
out.write(respxml);
out.flush();
out.close();
返回给微信服务器即可。