微信公眾號獲取使用者傳送的普通訊息
阿新 • • 發佈:2019-01-27
最近開始寫微信公眾號了,作為小白的我,有些懵,參考各種大神寫的部落格,總算實現了第一個功能。寫此部落格作為記錄吧。
我要實現的功能,簡單來說就是,獲取使用者向公眾號傳送的訊息,然後依據一定條件進行訊息篩選,符合要求的進行入庫操作。
話不多說,開始貼程式碼吧。
package com.weixin.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.weixin.entity.RequestTextMessage;
import com.weixin.entity.Serial;
import com.weixin.service.SerialService;
import com.weixin.util.ReplyMessage;
import com.weixin.util.SHA1;
@Controller
@RequestMapping
public class RecognitionSerialNumberController {
private static final Logger log =Logger.getLogger(RecognitionSerialNumberController.class);
// 設定一個全域性的token,開發者自己設定。api這樣解釋:Token可由開發者可以任意填寫,
// 用作生成簽名(該Token會和介面URL中包含的Token進行比對,從而驗證安全性)
private String TOKEN = "guoyou";
@Autowired
private SerialService serialService ;
@RequestMapping(value="/addSerialNumber.html")
public void addSerialNumber(HttpServletRequest request, HttpServletResponse response) throws Exception{
//checkToken(request, response); //僅在認證微信開發者模式時呼叫一次即可
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw = response.getWriter();
String wxMsgXml =IOUtils.toString(request.getInputStream(), "utf-8");
log.info("獲取的資料資訊>>>>>"+wxMsgXml);
boolean eventType =wxMsgXml.contains("Event") ;// 如果包含,則是觸發事件
RequestTextMessage textMsg =null ;
String returnXml ="";
StringBuffer replyMsg = new StringBuffer();
if(!eventType){ //資訊互動事件
textMsg = ReplyMessage.getRequestTextMessage(wxMsgXml);//解析使用者輸入的資訊
String content = textMsg.getContent().trim();//使用者傳送資訊
String openId= textMsg.getFromUserName().trim();//傳送方賬號(OpenID)
String creattime=textMsg.getCreateTime();
String msgType=textMsg.getMessageType();// 傳送型別
String tousername=textMsg.getToUserName();//使用者微訊號
boolean flag= isContainsNumOrLetter(content);
if(flag) {
//將資料入庫
Serial serial = new Serial();
serial.setAddtime(new Date());
serial.setOpen_id(openId);
serial.setName(tousername);
serial.setSn(content);
serial.setBt_mac_addr("");
serial.setWifi_mac_addr("");
serialService.insertSelective(serial);
//serialService.insert(serial);
replyMsg.append("返回資訊!");
returnXml = ReplyMessage.getReplyTextMessage(replyMsg.toString(), textMsg.getFromUserName(),textMsg.getToUserName());
}else {
replyMsg.append("輸入字元不符合格式!");
returnXml = ReplyMessage.getReplyTextMessage(replyMsg.toString(), textMsg.getFromUserName(),textMsg.getToUserName());
}
}
log.info("wxMsgXml>>>>>>>>>>>>>>"+wxMsgXml);
log.info("returnXml>>>>>>>>>>>>>>"+returnXml);
pw.println(returnXml);
}
/**
*
* @Title: isContainsNumOrLetter
* @Description: TODO(判斷字元是否符合要求即包含數字和字母且長度為12)
* @param @param str
* @param @return 引數
* @return boolean 返回型別
* @throws
*/
private boolean isContainsNumOrLetter(String str) {
boolean flag = false;
boolean isDigit = false;//定義一個boolean值,用來表示是否包含數字
boolean isLetter = false;//定義一個boolean值,用來表示是否包含字母
//假設有一個字串
for (int i=0 ; i<str.length() ; i++){ //迴圈遍歷字串
if (Character.isDigit(str.charAt(i))){ //用char包裝類中的判斷數字的方法判斷每一個字元
isDigit = true;
}
if (Character.isLetter(str.charAt(i))){ //用char包裝類中的判斷字母的方法判斷每一個字元
isLetter = true;
}
}
/*迴圈完畢以後
*如果isDigit為true,則代表字串中包含數字,否則不包含
*如果isLetter為true,則代表字串中包含字母,否則不包含
*/
//System.out.println(isDigit); //System.out.println(isLetter);
if(isDigit && isLetter) {
//根據字元長度、判斷輸入是Wifi 還是藍芽
int len=str.length();
if( len == 12) {
flag = true;
}
}
return flag;
}
/*
* 第一步:驗證伺服器地址的有效性 開發者提交資訊後,微信伺服器將傳送GET請求到填寫的伺服器地址URL上,
* GET請求攜帶四個引數:signature、timestamp、nonce、echostr
* 開發者通過檢驗signature對請求進行校驗(下面有校驗方式)。 若確認此次GET請求來自微信伺服器,請原樣返回echostr引數內容,
* 則接入生效, 成為開發者成功,否則接入失敗。
*
* 加密/校驗流程如下:
* 1. 將token、timestamp、nonce三個引數進行字典序排序
* 2. 將三個引數字串拼接成一個字串進行sha1加密
* 3. 開發者獲得加密後的字串可與signature對比,標識該請求來源於微信
*
* 字典排序(lexicographical order)是一種對於隨機變數形成序列的排序方法。其方法是,按照字母順序,或者數字小大順序,由小到大的形成序列。
*/
public boolean checkToken(HttpServletRequest request, HttpServletResponse response) throws IOException {
boolean flag = false;
// 微信加密簽名
String signature = request.getParameter("signature");
// 隨機字串
String echostr = request.getParameter("echostr");
// 時間戳
String timestamp = request.getParameter("timestamp");
// 隨機數
String nonce = request.getParameter("nonce");
String[] str = { TOKEN, timestamp, nonce };
Arrays.sort(str); // 字典序排序
String bigStr = str[0] + str[1] + str[2];
// SHA1加密
String digest = new SHA1().getDigestOfString(bigStr.getBytes()).toLowerCase();
// 確認請求來至微信
if (digest.equals(signature)) {
response.getWriter().print(echostr);
flag = true;
}else {
System.out.println("TAG"+"接入失敗");
}
return flag;
}
}
ReplyMessage.java
package com.weixin.util;
import java.util.Date;
import java.util.List;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.weixin.entity.Item;
import com.weixin.entity.ReplyTextMessage;
import com.weixin.entity.ReplyTuwenMessage;
import com.weixin.entity.RequestTextMessage;
public class ReplyMessage {
// 獲取關注事件
public static RequestTextMessage getRequestFocus(String xml){
XStream xstream = new XStream(new DomDriver());
xstream.alias("xml", RequestTextMessage.class);
xstream.aliasField("ToUserName", RequestTextMessage.class, "toUserName");
xstream.aliasField("FromUserName", RequestTextMessage.class, "fromUserName");
xstream.aliasField("CreateTime", RequestTextMessage.class, "createTime");
xstream.aliasField("MsgType", RequestTextMessage.class, "messageType");
xstream.aliasField("Event", RequestTextMessage.class, "event");
xstream.aliasField("EventKey", RequestTextMessage.class, "eventKey");
// xstream.aliasField("Content", RequestTextMessage.class, "content");
// xstream.aliasField("MsgId", RequestTextMessage.class, "msgId");
RequestTextMessage requestTextMessage = (RequestTextMessage)xstream.fromXML(xml);
return requestTextMessage;
}
// 獲取推送文字訊息
public static RequestTextMessage getRequestTextMessage(String xml){
XStream xstream = new XStream(new DomDriver());
xstream.alias("xml", RequestTextMessage.class);
xstream.aliasField("URL", RequestTextMessage.class, "url");
xstream.aliasField("ToUserName", RequestTextMessage.class, "toUserName");
xstream.aliasField("FromUserName", RequestTextMessage.class, "fromUserName");
xstream.aliasField("CreateTime", RequestTextMessage.class, "createTime");
xstream.aliasField("MsgType", RequestTextMessage.class, "messageType");
xstream.aliasField("Content", RequestTextMessage.class, "content");
xstream.aliasField("MsgId", RequestTextMessage.class, "msgId");
RequestTextMessage requestTextMessage = (RequestTextMessage)xstream.fromXML(xml);
return requestTextMessage;
}
// 回覆文字訊息
public static String getReplyTextMessage(String content, String fromUserName,String toUserName){
ReplyTextMessage we = new ReplyTextMessage();
we.setMessageType("text");
we.setFuncFlag("0");
we.setCreateTime(new Long(new Date().getTime()).toString());
we.setContent(content);
we.setToUserName(fromUserName);
we.setFromUserName(toUserName);
XStream xstream = new XStream(new DomDriver());
xstream.alias("xml", ReplyTextMessage.class);
xstream.aliasField("ToUserName", ReplyTextMessage.class, "toUserName");
xstream.aliasField("FromUserName", ReplyTextMessage.class, "fromUserName");
xstream.aliasField("CreateTime", ReplyTextMessage.class, "createTime");
xstream.aliasField("MsgType", ReplyTextMessage.class, "messageType");
xstream.aliasField("Content", ReplyTextMessage.class, "content");
xstream.aliasField("FuncFlag", ReplyTextMessage.class, "funcFlag");
String xml =xstream.toXML(we);
return xml;
}
// 回覆圖文訊息
public static String getReplyTuwenMessage(String fromUserName,String toUserName,List<Item> articleList){
// NewsMessage newsMessage = new NewsMessage();
// MessageUtil messageUtil = new MessageUtil();
ReplyTuwenMessage we = new ReplyTuwenMessage();
// List<Item> articleList = new ArrayList<>();
// Articles articles = new Articles();
// Item item = new Item();
// Item item2 = new Item();
// Item item3 = new Item();
we.setMessageType("news");
we.setCreateTime(new Long(new Date().getTime()).toString());
we.setToUserName(fromUserName);
we.setFromUserName(toUserName);
we.setFuncFlag("0");
we.setArticleCount(articleList.size());
we.setArticles(articleList);
XStream xstream = new XStream(new DomDriver());
xstream.alias("xml", ReplyTuwenMessage.class);
xstream.aliasField("ToUserName", ReplyTuwenMessage.class, "toUserName");
xstream.aliasField("FromUserName", ReplyTuwenMessage.class, "fromUserName");
xstream.aliasField("CreateTime", ReplyTuwenMessage.class, "createTime");
xstream.aliasField("MsgType", ReplyTuwenMessage.class, "messageType");
xstream.aliasField("Articles", ReplyTuwenMessage.class, "Articles");
xstream.aliasField("ArticleCount", ReplyTuwenMessage.class, "articleCount");
xstream.aliasField("FuncFlag", ReplyTuwenMessage.class, "funcFlag");
//xstream.aliasField("item", Articles.class, "item");
xstream.alias("item", new Item().getClass());
xstream.aliasField("Title", Item.class, "title");
xstream.aliasField("Description", Item.class, "description");
xstream.aliasField("PicUrl", Item.class, "picUrl");
xstream.aliasField("Url", Item.class, "url");
String xml =xstream.toXML(we);
return xml;
}
}
RequestTextMessage.java
package com.weixin.entity;
public class RequestTextMessage {
private String url;
private String toUserName;
private String fromUserName;
private String createTime;
private String messageType;
private String content;
private String msgId;
private String event;
private String eventKey;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getToUserName() {
return toUserName;
}
public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}
public String getFromUserName() {
return fromUserName;
}
public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getMessageType() {
return messageType;
}
public void setMessageType(String messageType) {
this.messageType = messageType;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public String getEvent() {
return event;
}
public void setEvent(String event) {
this.event = event;
}
public String getEventKey() {
return eventKey;
}
public void setEventKey(String eventKey) {
this.eventKey = eventKey;
}
}
獲取/回覆使用者傳送的其他型別訊息還未實現,有時間整理出來一併貼出來。革命尚未成功,還需努力呀。