上一篇讲述了如何向小程序用户推送公众号的模板消息,但是微信公众号的用户如何能获取到呢?
- 通过获取用户列表然后根据openId的数组循环请求用户信息,然后插入数据库
但是这种请求只能请求一次,不能一直用这种方式去进行请求。那么请求后的新用户如何放在本地数据库里呢?请往下看。
- 通过用户列表循环请求用户信息,然后放在本地数据库中,方法看上一篇文章。
- 步骤1执行完后,新的微信公众号的用户关注后微信端会向服务器发送一条xml请求(需要启用微信公众号的服务器配置)
//获取微信服务器发送的xml请求
@RequestMapping(value = "/serial", method = RequestMethod.POST)
public void checkSignPost(HttpServletRequest request,HttpServletResponse response) throws AesException, IOException{
// 将请求、响应的编码均设置为UTF-8(防止中文乱码)
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
System.out.println("请求进入");
String result = "";
try {
Map<String,String> map = WeCharHandlerUtil.parseXml(request);
System.out.println("开始构造消息");
System.out.println("返回xml数据:" + JSONObject.toJSON(map).toString());
result = WeCharHandlerUtil.buildXml(map);
System.out.println(result);
if(result.equals("")){
result = "未正确响应";
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("发生异常:"+ e.getMessage());
}
response.getWriter().println(result);
}
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
/**
* 解析微信发来的请求(XML)
* @param request
* @return map
* @throws Exception
*/
public static Map<String,String> parseXml(HttpServletRequest request) throws Exception {
// 将解析结果存储在HashMap中
Map<String,String> map = new HashMap();
// 从request中取得输入流
InputStream inputStream = request.getInputStream();
System.out.println("获取输入流");
// 读取输入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements();
// 遍历所有子节点
for (Element e : elementList) {
System.out.println(e.getName() + "|" + e.getText());
map.put(e.getName(), e.getText());
}
// 释放资源
inputStream.close();
inputStream = null;
return map;
}
// 根据消息类型 构造返回消息
public static String buildXml(Map<String,String> map) {
String result;
String msgType = map.get("MsgType").toString();
System.out.println("MsgType:" + msgType);
if(msgType.toUpperCase().equals("TEXT")){
result = buildTextMessage(map, "Hello World!");
} else if (msgType.toUpperCase().equals("EVENT")) {
String event = map.get("Event").toString();
if (event.toUpperCase().equals("SUBSCRIBE")) {
// TODO 处理关注公众号操作
System.out.println("有一个新的用户关注公众号");
} else if (event.toUpperCase().equals("UNSUBSCRIBE")) {
System.out.println("有一个新的用户取消关注公众号");
// TODO 处理取消关注公众号操作
}
} else{
String fromUserName = map.get("FromUserName");
// 开发者微信号
String toUserName = map.get("ToUserName");
result = String
.format(
"<xml>" +
"<ToUserName><![CDATA[%s]]></ToUserName>" +
"<FromUserName><![CDATA[%s]]></FromUserName>" +
"<CreateTime>%s</CreateTime>" +
"<MsgType><![CDATA[text]]></MsgType>" +
"<Content><![CDATA[%s]]></Content>" +
"</xml>",
fromUserName, toUserName, getUtcTime(),
"欢迎您关注本公众号");
}
return result;
}
/**
* 构造文本消息
*
* @param map
* @param content
* @return
*/
private static String buildTextMessage(Map<String,String> map, String content) {
//发送方帐号
String fromUserName = map.get("FromUserName");
// 开发者微信号
String toUserName = map.get("ToUserName");
/**
* 文本消息XML数据格式
*/
return String.format(
"<xml>" +
"<ToUserName><![CDATA[%s]]></ToUserName>" +
"<FromUserName><![CDATA[%s]]></FromUserName>" +
"<CreateTime>%s</CreateTime>" +
"<MsgType><![CDATA[text]]></MsgType>" +
"<Content><![CDATA[%s]]></Content>" + "</xml>",
fromUserName, toUserName, getUtcTime(), content);
}
private static String getUtcTime() {
Date dt = new Date();// 如果不需要格式,可直接用dt,dt就是当前系统时间
DateFormat df = new SimpleDateFormat("yyyyMMddhhmm");// 设置显示格式
String nowTime = df.format(dt);
long dd = (long) 0;
try {
dd = df.parse(nowTime).getTime();
} catch (Exception e) {
}
return String.valueOf(dd);
}
以上为获取微信公众号关注和取消关注的信息。