在前几节中,我们把验证开发者的步骤、获取微信的token和微信的中控服务器相关接口已经设计好了。今天我们来说一下微信的收取消息的功能。如果对我的文章感兴趣,欢迎订阅我的头条号,一点热,yeehot.com
今天我们说的微信收取的内容,看了微信的文档,里面说到微信的信息的收取是通过post的方式,然后发送到我们验证开发者的URL上,由于我们之前写的文档只是用于接收验证开发者的get的请求,现在突然接收到post的数据,这样设计就存在问题。所以我们需要对我们的接口进行修改一下。
在spring MVC如果我们要同时接收get和post的方法,那么我们可以不用知道里面接收的方法,由于我上一节把格式固定成get了,那么我们是无法收到post的数据的,所以我们要把它删除了,此外我们还需要将字符转换成UTF-8格式的。produces = "text/plain;charset=utf-8",写上这样的代码就可以转换了。当然我们也需要web.xml配置一下。
web.xml
我们需要把之前验证开发者的的controller的代码改成如下:主要是删除get方法,增加UTF-8编码
java使用spring mvc开发微信公众号验证开发者步骤
@Controller
public class WeixinController {
@ResponseBody
@RequestMapping(value = "/wx/developer", produces = "text/plain;charset=utf-8")
public String index(HttpServletRequest request) {
}
接着由于同时有验证的信息和消息进入到这里,那么我们需要判断一下方法,由于验证的入口是通过get请求的,然后消息的接收是通过post的,所以我们可以通过request获取传递数据的方法:我们可以通过request.getMethod()来检查,如果是get就进行开发者验证的步骤。否则就进行消息的收发
String method=request.getMethod();
System.out.print(method+"?");
if (method.equals("GET")) {
Map
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
params.put(name, valueStr);
}
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
String token = "wx1111";
String sign = digest(params, token);
if (sign.equals(signature)) {
return echostr;
} else {
return "";
}
}
接着我们可以写消息的收发的步骤了,我们就以微信的文本内容作为例子,写一个接收文本的内容,然后我自动回复我们输入的内容。我们从微信的文档看到,微信收到普通的消息后会包含如下的内容。也是一个XML格式的数据,详细代表什么内容,我就不做解析了,文档已经说得很清楚了。
其实我们可以使用postman来本地模拟一下这个数据到我们的开发者接口进行本地写代码,不过要在body输入原始数据:
这样我们可以处理post的请求了:我这里定义一个接收数据会自动返回数据的MAP,首先我们接收微信发送过来的原始数据,并转换成String型,并将里面的内容通过XML解析工具转换成MAP,接着我们将接收的数据MAP读取出来,然后接着存入到返回的数据的MAP。再将数据封装成XML格式的字符串,如果服务器读取不了,我们直接返回success;
else {
Map
Map
StringBuffer jb = new StringBuffer();
String line = null;
BufferedReader reader = null;
try {
reader = request.getReader();
while ((line = reader.readLine()) != null)
{
jb.append(line);
}
System.out.print(jb.toString());
postmessage=XmlParseTool.doXMLParse(jb.toString());
responsemessage.put("ToUserName",postmessage.get("FromUserName"));//我们要返回到发送者这里
responsemessage.put("FromUserName",postmessage.get("ToUserName"));//微信开发者号
responsemessage.put("CreateTime",String.valueOf(System.currentTimeMillis()));
responsemessage.put("MsgType",postmessage.get("MsgType"));
responsemessage.put("Content","我们已经收到你的内容了:"+postmessage.get("Content"));
;
return XmlParseTool.RequestXml2String(responsemessage,true);
}
catch (JDOMException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return "success";
}
接着,我们可以写一个格式转换工具XmlParseTool类,doXMLParse的方法,我们之前都用到,这些方法将伴随着我们整个微信公众号开发中
public static Map
if(null == inputinfo || "".equals(inputinfo)) {
return null;
}
Map
InputStream in =new ByteArrayInputStream(inputinfo.getBytes("utf-8"));
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(in);
Element root = doc.getRootElement();
List list = root.getChildren();
Iterator it = list.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String k = e.getName();
String v = "";
List children = e.getChildren();
if(children.isEmpty()) {
v = e.getTextNormalize();
} else {
v = getChildrenText(children);
}
m.put(k, v);
}
in.close();
return m;
}
public static String getChildrenText(List children) {
StringBuffer sb = new StringBuffer();
if(!children.isEmpty()) {
Iterator it = children.iterator();
while(it.hasNext()) {
Element e = (Element) it.next();
String name = e.getName();
String value = e.getTextNormalize();
List list = e.getChildren();
sb.append("<" + name + ">");
if(!list.isEmpty()) {
sb.append(getChildrenText(list));
}
sb.append(value);
sb.append("" + name + ">");
}
}
return sb.toString();
}
接着我们还需要写一个返回XML格式字符串的工具,而且还有判断里面的字符是否加上CDATA,不过我是看消息收发的字符这里,检查文本消息,图片消息,视频消息等,里面有CreateTime和ArticleCount是不需要加上CDATA格式的,所以我们直接过滤这两个字符。
public static String RequestXml2String(Map
StringBuffer sb = new StringBuffer();
sb.append("
Set es = params.entrySet();
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
String v = (String)entry.getValue();
if ("CreateTime".equalsIgnoreCase(k)||"ArticleCount".equalsIgnoreCase(k)) {
sb.append("<"+k+">"+v+""+k+">");
}else {
sb.append("<"+k+">"+""+k+">");
}
}
sb.append("");
return sb.toString();
}
最后我们部署到服务器验证一下,我直接用测试号来验证
今天就讲到这里,欢迎继续关注我的头条号:一点热,如果有什么问题,欢迎留言咨询,我看到之后会第一时间回复大家的。如果需要转载到其他网站,请与我联系。
本文暂时没有评论,来添加一个吧(●'◡'●)