前面已经搞好了微信服务器配置,和生成了带参二维码,现在就是微信扫码事件的实现,未关注的先关注在推送,关注过公众号的直接推送。
之前也是在配置好的微信服务器,下面的扫码事件也要写那个方法里,这样才可以和微信服务器 “交流” 推送消息。
下面是代码
@Controller
@RequestMapping(value = "/vatToken")
public class VatifyToken {
@ResponseBody
@RequestMapping(method = RequestMethod.POST)
public String toVatifyTokenPost(HttpServletRequest request, HttpServletResponse response, ModelMap map) {
String returnXml = "";
String respMessage= "";
try {
String xmlData = null;
try {
xmlData = StreamUtils.copyToString(request.getInputStream(), Charset.forName("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
Map<String, String> mapData = XMLConverUtil.convertToMap(xmlData);
String event = mapData.get("Event");
// 发送方帐号(open_id)
String fromUserName = mapData.get("FromUserName");
// 公众帐号
String toUserName = mapData.get("ToUserName");
if ("event".equals(msgType)) { // 事件消息
// 区分事件推送
String event = mapData.get("Event");
System.out.println("****区分事件推送****"+event);
if ("subscribe".equals(event)) { // 订阅事件 或 未关注扫描二维码事件
List<Article> articleList = new ArrayList<Article>();
NewsMessage newsMessage = new NewsMessage();
newsMessage.setToUserName(fromUserName);
newsMessage.setFromUserName(toUserName);
newsMessage.setCreateTime(new Date().getTime());
newsMessage.setMsgType("news");
newsMessage.setFuncFlag(0);
Article article1 = new Article();
article1.setTitle("我是一条多图文消息");
article1.setDescription("");
article1.setPicUrl("http://pic37.nipic.com/20140113/8800276_184927469000_2.png");
article1.setUrl("https://www.baidu.com/");
Article article2 = new Article();
article2.setTitle("微信公众平台开发教程Java版(二)接口配置 ");
article2.setDescription("");
article2.setPicUrl("https://www.baidu.com/img/bd_logo1.png?where=super");
article2.setUrl("http://tuposky.iteye.com/blog/2008655");
/*Article article3 = new Article();
article3.setTitle("微信公众平台开发教程Java版(三) 消息接收和发送");
article3.setDescription("");
article3.setPicUrl("https://www.baidu.com/img/bd_logo1.png?where=super");
article3.setUrl("http://tuposky.iteye.com/blog/2017429");*/
articleList.add(article1);
articleList.add(article2);
//articleList.add(article3);
newsMessage.setArticleCount(articleList.size());
newsMessage.setArticles(articleList);
respMessage=MessageUtil.newsMessageToXml(newsMessage);
} else if ("SCAN".equals(event)) { // 已关注扫描二维码事件
List<Article> articleList = new ArrayList<Article>();
NewsMessage newsMessage = new NewsMessage();
newsMessage.setToUserName(fromUserName);
newsMessage.setFromUserName(toUserName);
newsMessage.setCreateTime(new Date().getTime());
newsMessage.setMsgType("news");
newsMessage.setFuncFlag(0);
Article article1 = new Article();
article1.setTitle("显示名称");
article1.setDescription("");
article1.setPicUrl("http://img5.imgtn.bdimg.com/it/u=3300305952,1328708913&fm=26&gp=0.jpg");
article1.setUrl("http://tuposky.iteye.com/blog/2008583");
Article article2 = new Article();
article2.setTitle("这里是测试 ");
article2.setDescription("");
article2.setPicUrl("http://img5.imgtn.bdimg.com/it/u=1337727530,4187567521&fm=26&gp=0.jpg");
article2.setUrl("http://tuposky.iteye.com/blog/2008655");
Article article3 = new Article();
article3.setTitle("这里是测试1");
article3.setDescription("");
article3.setPicUrl("https://www.baidu.com/img/bd_logo1.png?where=super");
article3.setUrl("http://tuposky.iteye.com/blog/2017429");
articleList.add(article1);
articleList.add(article2);
articleList.add(article3);
newsMessage.setArticleCount(articleList.size());
newsMessage.setArticles(articleList);
respMessage=MessageUtil.newsMessageToXml(newsMessage);
System.out.println("---------------xml------"+respMessage);
} else if ("LOCATION".equals(event)) { // 上报地理位置事件
// todo 处理上报地理位置事件
} else if ("CLICK".equals(event)) { // 点击菜单拉取消息时的事件推送事件
// todo 处理点击菜单拉取消息时的事件推送事件
} else if ("VIEW".equals(event)) { // 点击菜单跳转链接时的事件推送
// todo 处理点击菜单跳转链接时的事件推送
}
}
}catch (Exception e){
LOG.info("接收事件推送:"+e.toString());
}
return "";
}
}
下面是封装的方法
public static String copyToString(InputStream in, Charset charset) throws IOException {
StringBuilder out = new StringBuilder();
InputStreamReader reader = new InputStreamReader(in, charset);
char[] buffer = new char[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = reader.read(buffer)) != -1) {
out.append(buffer, 0, bytesRead);
}
return out.toString();
}
XML转map
public static Map<String,String> convertToMap(String xml){
Map<String, String> map = new LinkedHashMap<String,String>();
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(xml);
InputSource is = new InputSource(sr);
Document document = db.parse(is);
Element root = document.getDocumentElement();
if(root != null){
NodeList childNodes = root.getChildNodes();
if(childNodes != null && childNodes.getLength()>0){
for(int i = 0;i < childNodes.getLength();i++){
Node node = childNodes.item(i);
if( node != null && node.getNodeType() == Node.ELEMENT_NODE){
map.put(node.getNodeName(), node.getTextContent());
}
}
}
}
} catch (DOMException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
图文消息实体类 Article
package com.wechat.model.wxMsgRes;
/**
* 图文消息
*
*/
public class Article {
/**
* 图文消息名称
*/
private String Title;
/**
* 图文消息描述
*/
private String Description;
/**
* 图片链接,支持JPG、PNG格式,<br>
* 较好的效果为大图640*320,小图80*80
*/
private String PicUrl;
/**
* 点击图文消息跳转链接
*/
private String Url;
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public String getDescription() {
return null == Description ? "" : Description;
}
public void setDescription(String description) {
Description = description;
}
public String getPicUrl() {
return null == PicUrl ? "" : PicUrl;
}
public void setPicUrl(String picUrl) {
PicUrl = picUrl;
}
public String getUrl() {
return null == Url ? "" : Url;
}
public void setUrl(String url) {
Url = url;
}
}
封装多个图文消息 NewsMessage
package com.wechat.model.wxMsgRes;
import java.util.List;
/**
* 多图文消息,
* 单图文的时候 Articles 只放一个就行了
*/
public class NewsMessage extends BaseMessage {
/**
* 图文消息个数,限制为10条以内
*/
private int ArticleCount;
/**
* 多条图文消息信息,默认第一个item为大图
*/
private List<Article> Articles;
public int getArticleCount() {
return ArticleCount;
}
public void setArticleCount(int articleCount) {
ArticleCount = articleCount;
}
public List<Article> getArticles() {
return Articles;
}
public void setArticles(List<Article> articles) {
Articles = articles;
}
}
BaseMessage
package com.wechat.model.wxMsgRes;
/**
* 消息基类(公众帐号 -> 用户)
*/
public class BaseMessage {
/**
* 接收方帐号(收到的OpenID)
*/
private String ToUserName;
/**
* 开发者微信号
*/
private String FromUserName;
/**
* 消息创建时间 (整型)
*/
private long CreateTime;
/**
* 消息类型
*/
private String MsgType;
/**
* 位0x0001被标志时,星标刚收到的消息
*/
private int FuncFlag;
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;
}
public int getFuncFlag() {
return FuncFlag;
}
public void setFuncFlag(int funcFlag) {
FuncFlag = funcFlag;
}
}
图文消息对象转换成xml
/**
* 图文消息对象转换成xml
*
* @param newsMessage 图文消息对象
* @return xml
*/
public static String newsMessageToXml(NewsMessage newsMessage) {
xstream.alias("xml", newsMessage.getClass());
xstream.alias("item", new Article().getClass());
return xstream.toXML(newsMessage);
}
这样的话应该就可以接收到推送的消息了。