作者:bj韩式尕伙 | 来源:互联网 | 2023-09-07 14:24
上一节内容:
微信开发学习总结(二)——微信开发环境准备(2)
https://blog.csdn.net/qq_29914837/article/details/82896861
接收普通消息
当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。
请注意:
1、关于重试的消息排重,推荐使用msgid排重。
2、微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。详情请见“发送消息-被动回复消息”。
3、如果开发者需要对用户消息在5秒内立即做出回应,即使用“发送消息-被动回复消息”接口向用户被动回复消息时,可以在公众平台官网的开发者中心处设置消息加密。开启加密后,用户发来的消息和开发者回复的消息都会被加密(但开发者通过客服接口等API调用形式向用户发送消息,则不受影响)。关于消息加解密的详细说明,请见“发送消息-被动回复消息加解密说明”。
一、文本消息推送XML数据包结构
1348831860 1234567890123456
参数 | 描述 |
---|
ToUserName | 开发者微信号 |
FromUserName | 发送方帐号(一个OpenID) |
CreateTime | 消息创建时间 (整型) |
MsgType | text |
Content | 文本消息内容 |
MsgId | 消息id,64位整型 |
| |
二、接收微信服务器发送的消息并做出响应
通过下面代码来实现接收微信服务器发送的消息并做出响应的功能。
当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上(也就是我们在服务器配置的URL)。
①WeiXinCheck.java(工具类,包含各种常用方法)
package weixin.util;import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import net.sf.json.JSONObject;
import weixin.entity.accesstoken.AccessToken;/*** @所属类别:工具类* @用途:微信开发校验方法、sha1加密算法等* @author yilei* @version:1.0*/
public class WeiXinCheck {/*** @method 将token、timestamp、nonce三个参数进行字典序排序* @param token* @param timestamp* @param nonce* @return 排序后的字符串*/public static String sort(String token, String timestamp, String nonce) {String[] strArray = { token, timestamp, nonce };Arrays.sort(strArray);StringBuilder sb = new StringBuilder();for (String str : strArray) {sb.append(str);}return sb.toString();}/*** @method 将三个参数字符串拼接成一个字符串进行sha1加密* @param str,需要加密的字符串(排序后的字符串)* @return 加密后的内容*/public static String sha1(String str) {try {MessageDigest digest = MessageDigest.getInstance("SHA-1");digest.update(str.getBytes());byte messageDigest[] = digest.digest();// Create Hex StringStringBuffer hexString = new StringBuffer();// 字节数组转换为 十六进制 数for (int i = 0; i parseXml(HttpServletRequest request) throws Exception {// 将解析结果存储在HashMap中Map map = new HashMap();// 从request中取得输入流InputStream inputStream = request.getInputStream();// 读取输入流SAXReader reader = new SAXReader();Document document = reader.read(inputStream);// 得到xml根元素Element root = document.getRootElement();// 得到根元素的所有子节点List elementList = root.elements();// 遍历所有子节点for (Element e : elementList) {System.out.println(e.getName() + "|" + e.getText());map.put(e.getName(), e.getText());}// 释放资源inputStream.close();return map;}// 根据消息类型 构造返回消息public static String buildXml(Map map) {String result;String msgType = map.get("MsgType").toString();if(msgType.toUpperCase().equals("TEXT")){//文本消息result = buildTextMessage(map, "欢迎猪牧狼马蜂YY,消息类型:文本消息");}else{String fromUserName = map.get("FromUserName");// 开发者微信号String toUserName = map.get("ToUserName");result = String.format("" +"" +"" +"%s" +"" +"" +"",fromUserName, toUserName, getCreateTime(),"请回复如下关键词:\n文本\n图片\n语音\n视频\n音乐\n图文");}return result;}/*** 构造文本消息* @param map* @param content* @return*/private static String buildTextMessage(Map map, String content) {//发送方帐号String fromUserName = map.get("FromUserName");// 开发者微信号String toUserName = map.get("ToUserName");return String.format("" +"" +"" +"%s" +"" +"" + "",fromUserName, toUserName, getCreateTime(), content);}/*** 格式化日期格式* @return 格式化的日期*/public static String getCreateTime() {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);}}
②MainApplication.java (微信开发接口入口)
package weixin;import java.io.IOException;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import weixin.util.WeiXin;
import weixin.util.WeiXinCheck;
/*** @所属类别:servlet类* @用途:微信开发接口入口* @author yilei* @version:1.0*/
public class MainApplication extends HttpServlet{/*** 开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上(校验签名是否通过,通过才可以进行微信开发其他操作)* @param request* @param response* @throws IOException */@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// TODO Auto-generated method stubSystem.out.println("开始校验签名");//接收微信服务器发送请求时传递过来的4个参数String signature = request.getParameter("signature");//微信加密签名signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。String timestamp = request.getParameter("timestamp");//时间戳String nonce = request.getParameter("nonce");//随机数String echostr = request.getParameter("echostr");//随机字符串//排序String sortString = WeiXinCheck.sort(WeiXin.TOKEN, timestamp, nonce);//sha1加密String mySignature = WeiXinCheck.sha1(sortString);//校验签名if (WeiXinCheck.equalSignature(mySignature, signature)) {System.out.println("签名校验通过。");//如果检验成功输出echostr,微信服务器接收到此输出,才会确认检验完成。//response.getWriter().println(echostr);response.getWriter().println(echostr);} else {System.out.println("签名校验失败.");}}/*** 处理微信服务器发来的消息*/@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// TODO 接收、处理、响应由微信服务器转发的用户发送给公众帐号的消息// 将请求、响应的编码均设置为UTF-8(防止中文乱码)request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");System.out.println("微信的post请求进入了本地服务器了");String result = "";try {Map map = WeiXinCheck.parseXml(request);System.out.println("微信公众号要开始发送消息");result = WeiXinCheck.buildXml(map);System.out.println(result);if(result.equals("")){result = "未正确响应";}} catch (Exception e) {e.printStackTrace();System.out.println("发生异常:"+ e.getMessage());}response.getWriter().println(result);}}
启动服务器,具体步骤参考前面几节课程
然后,关注微信测试公众号
微信开发学习总结(三)——消息管理(1)——项目源码
下载地址:
https://download.csdn.net/download/qq_29914837/10696854
下一节内容:
微信开发学习总结(三)——消息管理(2)
https://blog.csdn.net/qq_29914837/article/details/82904454