refer : https://mp.weixin.qq.com/wiki
第一步:填寫服務器配置
注意:填完了之後先不要點確定,先做第二步,做完第二步再點確定。
第二步:驗證消息的確來自微信服務器 並返回數據
開發者通過檢驗signature對請求進行校驗(下面有校驗方式)。若確認此次GET請求來自微信服務器,請原樣返回echostr參數內容,則接入生效,成爲開發者成功,否則接入失敗。加密/校驗流程如下:
1)將token、timestamp、nonce三個參數進行字典序排序
2)將三個參數字符串拼接成一個字符串進行sha1加密
3)開發者獲得加密後的字符串可與signature對比,標識該請求來源於微信
要想快速通過,不檢驗也可以,直接返回echostr的內容即可。
附上java的代碼:
@RequestMapping("/wx/getMsg.htm")
public ModelAndView mock(String echostr, HttpSession httpSession, HttpServletResponse response,HttpServletRequest request) throws Exception{
if ( ! StringUtil.isNull(request.getParameter("echostr"))) {
PrintWriter writer = response.getWriter();
writer.print(request.getParameter("echostr"));
writer.flush();
writer.close();
return null;
}
System.out.println(request.getRequestURL());
System.out.println(request.getQueryString());
// 取HTTP請求流
ServletInputStream sis = request.getInputStream();
// 取HTTP請求流長度
int size = request.getContentLength();
if (size<0) return null;
// 用於緩存每次讀取的數據
byte[] buffer = new byte[size];
// 用於存放結果的數組
byte[] xmldataByte = new byte[size];
int count = 0;
int rbyte = 0;
// 循環讀取
while (count < size) {
// 每次實際讀取長度存於rbyte中
rbyte = sis.read(buffer);
for(int i=0;i<rbyte;i++) {
xmldataByte[count + i] = buffer[i];
}
count += rbyte;
}
String xmlData = new String(xmldataByte, "UTF-8");
System.out.println("recv from wx ->" + xmlData);
WxTextMsgBean wx = new WxTextMsgBean();
XMLUtil.parserWXRecvMsgxml(xmlData, wx );
String rtnStr = XMLUtil.createWXSendMsgXml(wx, "我就是不告訴你,不服你來打我啊。");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.print(rtnStr);
writer.flush();
writer.close();
return null;
}
XML解析相關:
package xm.web.utils;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import xm.web.bean.wx.msg.WxTextMsgBean;
public class XMLUtil {
public static String createWXSendMsgXml(WxTextMsgBean msg, String textMsgContent) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
Element root = document.createElement("xml");
document.appendChild(root);
// add a node
Element toUserName = document.createElement("ToUserName");
root.appendChild(toUserName);
toUserName.appendChild(document.createCDATASection(msg.getFromUserName()));
Element fromUserName = document.createElement("FromUserName");
root.appendChild(fromUserName);
fromUserName.appendChild(document.createCDATASection(msg.getToUserName()));
Element createTime = document.createElement("CreateTime");
root.appendChild(createTime);
createTime.appendChild(document.createTextNode(String.valueOf(System.currentTimeMillis())));
Element msgType = document.createElement("MsgType");
root.appendChild(msgType);
msgType.appendChild(document.createCDATASection("text"));
Element content = document.createElement("Content");
root.appendChild(content);
content.appendChild(document.createCDATASection(textMsgContent));
String rtn = toStringFromDoc(document);
rtn = rtn.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "");
System.out.println(rtn);
return rtn;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
/**
* 解析微信發來的【文本】消息
* @param xmlStr 字符串xml
* @param wx WxRecvMsgBean 用來存放解析結果
*/
public static void parserWXRecvMsgxml(String xmlStr, WxTextMsgBean wx) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
StringReader sr = new StringReader(xmlStr);
InputSource is = new InputSource(sr);
Document doc = builder.parse(is);
NodeList nodeList=doc.getElementsByTagName("*");
for(int i=0;i<nodeList.getLength();i++){
switch (nodeList.item(i).getNodeName()) {
case "ToUserName":
wx.setToUserName(nodeList.item(i).getTextContent());
break;
case "FromUserName":
wx.setFromUserName(nodeList.item(i).getTextContent());
break;
case "CreateTime":
wx.setCreateTime(nodeList.item(i).getTextContent());
break;
case "MsgType":
wx.setMsgType(nodeList.item(i).getTextContent());
break;
case "Content":
wx.setContent(nodeList.item(i).getTextContent());
break;
case "MsgId":
wx.setMsgId(nodeList.item(i).getTextContent());
break;
default:
break;
}
}
}catch(ParserConfigurationException e){
e.printStackTrace();
}catch (SAXException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
/*
* 把dom文件轉換爲xml字符串
*/
public static String toStringFromDoc(Document document) {
String result = null;
document.setXmlStandalone(false);
if (document != null) {
StringWriter strWtr = new StringWriter();
StreamResult strResult = new StreamResult(strWtr);
TransformerFactory tfac = TransformerFactory.newInstance();
try {
javax.xml.transform.Transformer t = tfac.newTransformer();
// t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
t.setOutputProperty(OutputKeys.INDENT, "yes");
// t.setOutputProperty(OutputKeys.METHOD, "xml");
// text
// t.setOutputProperty(
// "{http://xml.apache.org/xslt}indent-amount", "4");
// t.clearParameters();
t.transform(new DOMSource(document.getDocumentElement()),
strResult);
} catch (Exception e) {
System.err.println("XML.toString(Document): " + e);
}
result = strResult.getWriter().toString();
try {
strWtr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
}
package xm.web.bean.wx.msg;
public class WxTextMsgBean {
private String toUserName;
private String fromUserName;
private String createTime;
private String msgType;
private String content;
private String msgId;
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 getMsgType() {
return msgType;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
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;
}
}
附上調試的鏈接:
https://mp.weixin.qq.com/debug/