软件编程
位置:首页>> 软件编程>> java编程>> springboot实现公众号接收回复消息和超过5秒被动回复消息

springboot实现公众号接收回复消息和超过5秒被动回复消息

作者:豆趣编程  发布时间:2022-10-16 04:40:48 

标签:springboot,公众号,接收回复

本次就是记录一下我的开发过程,不是教程,纯属自己做个笔记。

现在项目有个需求,需要用户在公众号发送图片消息的时候,我后台程序能接收到这个图片,并用ai处理图片并返回信息。

1.首先第一步要接收微信消息,需要在公众号里设置与开发-基本配置里配置一下服务器配置

springboot实现公众号接收回复消息和超过5秒被动回复消息

这个url配置了以后,所以微信公众号的消息都会被推送到这个url对应的接口上,Token感觉没啥用,随便写一个完事,加密随机生成,不加密消息的话也没用。

最坑爹的是在提交配置的时候,微信要根据你填的这个url验证一下token认证,而这个url实际是后台处理消息的接口,搞不清楚咋肥四,我就先把这个接口写成验证token的,等提交完配置再改回我的处理消息接口代码。验证token这里随便找了段代码,亲测有效。

@RequestMapping(value = "/testToken")
public void testToken(HttpServletRequest request, HttpServletResponse response) throws Exception {
   String token="tokenxxx";
   logger.error("WechatController   ----   WechatController");
   System.out.println("========WechatController========= ");
   logger.info("请求进来了...");
   Enumeration pNames = request.getParameterNames();
   while (pNames.hasMoreElements()) {
       String name = (String) pNames.nextElement();
       String value = request.getParameter(name);
       // out.print(name + "=" + value);

String log = "name =" + name + "     value =" + value;
       logger.error(log);
   }
   String signature = request.getParameter("signature");/// 微信加密签名
   String timestamp = request.getParameter("timestamp");/// 时间戳
   String nonce = request.getParameter("nonce"); /// 随机数
   String echostr = request.getParameter("echostr"); // 随机字符串
   PrintWriter out = response.getWriter();
   out.print(echostr);
   out.close();

}

2.配置好公众号以后,开始接收微信消息

官方文档在这里:文本消息 | 微信开放文档

也就是说微信会给你发送xml格式的消息,后台需要能接收这个消息

要接收xml消息和以后发送消息啥的,需要先引入一些依赖:

<dependency>
           <groupId>com.fasterxml.jackson.dataformat</groupId>
           <artifactId>jackson-dataformat-xml</artifactId>
       </dependency>
       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-databind</artifactId>
           <version>2.10.0</version>
       </dependency>
       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-core</artifactId>
           <version>2.10.0</version>
       </dependency>
       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-annotations</artifactId>
           <version>2.10.0</version>
       </dependency>

<dependency>
           <groupId>com.fasterxml.jackson.jaxrs</groupId>
           <artifactId>jackson-jaxrs-xml-provider</artifactId>
       </dependency>
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
       </dependency>
       <!--httpUtil-->
       <dependency>
           <groupId>org.apache.httpcomponents</groupId>
           <artifactId>httpcore</artifactId>
           <version>4.4.10</version>
       </dependency>
       <dependency>
           <groupId>org.apache.httpcomponents</groupId>
           <artifactId>httpclient</artifactId>
           <version>4.5.6</version>
       </dependency>
       <!--解析微信的消息-->
       <dependency>
           <groupId>dom4j</groupId>
           <artifactId>dom4j</artifactId>
           <version>1.6</version>
       </dependency>
       <dependency>
           <groupId>com.thoughtworks.xstream</groupId>
           <artifactId>xstream</artifactId>
           <version>1.4.4</version>
       </dependency>

以为对应的图标消息是这样的:

springboot实现公众号接收回复消息和超过5秒被动回复消息

所以写个消息的实体类:

package com.bomc.recordLife.entry;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@Data
@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName  = "xml")
public class WxMessageImg {
   @JacksonXmlProperty(localName  = "ToUserName")
   private String ToUserName;
   @JacksonXmlProperty(localName  = "FromUserName")
   private String FromUserName;
   @JacksonXmlProperty(localName  = "CreateTime")
   private long  CreateTime;
   @JacksonXmlProperty(localName  = "MsgType")
   private String MsgType;
   @JacksonXmlProperty(localName  = "Event")
   private String Event;
   @JacksonXmlProperty(localName  = "PicUrl")
   private String PicUrl;
   @JacksonXmlProperty(localName  = "MediaId")
   private String MediaId;
   @JacksonXmlProperty(localName  = "MsgId")
   private long  MsgId;
   @JacksonXmlProperty(localName  = "Content")
   private String Content;

}

还是先记录一下如果不怕超时直接给用户返回消息的情况:

@PostMapping(value = "analyzeImg2",consumes = "text/xml", produces = "text/xml;charset=utf-8")
@ResponseBody
public Object analyzeImg2(@RequestBody WxMessageImg wxMessageImg){

//拼一下要返回的信息对象
   WxMessageImg resultMessage=new WxMessageImg();
   try {
           //忽略图片逻辑,直接闹个结果
           String resultStr="处理完图片返回的信息";

String openid = wxMessageImg.getFromUserName(); //用户 openid
           String mpid = wxMessageImg.getToUserName();   //公众号原始 ID
               resultMessage.setToUserName(openid);
               resultMessage.setFromUserName(mpid);
               resultMessage.setCreateTime(new Date().getTime());
               resultMessage.setContent(resultStr);
               resultMessage.setMsgType("text");
               //用这个工具类处理出一串玩意直接返回
               String outMesStr = WxMessageUtil.textMessageToXml(resultMessage);
               System.out.println(outMesStr);
               return outMesStr;

} catch (Exception e) {
       e.printStackTrace();
   }

return null;
}

工具类:

package com.bomc.recordLife.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bomc.recordLife.entry.WxMessageImg;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @Description: 消息工具类
* @Author: lst
* @Date 2020-08-19
*/
public class WxMessageUtil {

/**
    * 返回消息类型:文本
    */
   public static final String RESP_MESSAGE_TYPE_TEXT = "text";

/**
    * 返回消息类型:音乐
    */
   public static final String RESP_MESSAGE_TYPE_MUSIC = "music";

/**
    * 返回消息类型:图文
    */
   public static final String RESP_MESSAGE_TYPE_NEWS = "news";

/**
    * 返回消息类型:图片
    */
   public static final String RESP_MESSAGE_TYPE_Image = "image";

/**
    * 返回消息类型:语音
    */
   public static final String RESP_MESSAGE_TYPE_Voice = "voice";

/**
    * 返回消息类型:视频
    */
   public static final String RESP_MESSAGE_TYPE_Video = "video";

/**
    * 请求消息类型:文本
    */
   public static final String REQ_MESSAGE_TYPE_TEXT = "text";

/**
    * 请求消息类型:图片
    */
   public static final String REQ_MESSAGE_TYPE_IMAGE = "image";

/**
    * 请求消息类型:链接
    */
   public static final String REQ_MESSAGE_TYPE_LINK = "link";

/**
    * 请求消息类型:地理位置
    */
   public static final String REQ_MESSAGE_TYPE_LOCATION = "location";

/**
    * 请求消息类型:音频
    */
   public static final String REQ_MESSAGE_TYPE_VOICE = "voice";

/**
    * 请求消息类型:视频
    */
   public static final String REQ_MESSAGE_TYPE_VIDEO = "video";

/**
    * 请求消息类型:推送
    */
   public static final String REQ_MESSAGE_TYPE_EVENT = "event";

/**
    * 事件类型:subscribe(订阅)
    */
   public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";

/**
    * 事件类型:unsubscribe(取消订阅)
    */
   public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";

/**
    * 事件类型:CLICK(自定义菜单点击事件)
    */
   public static final String EVENT_TYPE_CLICK = "CLICK";

/**
    * 事件类型:VIEW(自定义菜单URl视图)
    */
   public static final String EVENT_TYPE_VIEW = "VIEW";

/**
    * 事件类型:LOCATION(上报地理位置事件)
    */
   public static final String EVENT_TYPE_LOCATION = "LOCATION";

/**
    * 事件类型:LOCATION(上报地理位置事件)
    */
   public static final String EVENT_TYPE_SCAN = "SCAN";

/**
    * @Description: 解析微信发来的请求(XML)
    * @param @param request
    * @param @return
    * @param @throws Exception
    * @author dapengniao
    * @date 2016年3月7日 上午10:04:02
    */
   public static Map<String, String> parseXml(HttpServletRequest request) {
       // 将解析结果存储在HashMap中
       Map<String, String> map = new HashMap<String, String>();

// 读取输入流
       SAXReader reader = new SAXReader();
       Document document = null;
       InputStream inputStream = null;
       try {
           // 从request中取得输入流
           inputStream = request.getInputStream();
           document = reader.read(inputStream);
           // 得到xml根元素
           Element root = document.getRootElement();
           // 得到根元素的所有子节点
           List<Element> elementList = root.elements();

// 遍历所有子节点
           elementList.stream().forEach(element -> {
               map.put(element.getName(), element.getStringValue());
           });
       } catch (DocumentException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }finally {
           // 释放资源
           if(null != inputStream){
               try {
                   inputStream.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }

return map;
   }

/**
    * @Description: 文本消息对象转换成xml
    * @param @param textMessage
    * @param @return
    * @author dapengniao
    * @date 2016年3月8日 下午4:13:22
    */
   public static String textMessageToXml(WxMessageImg textMessage) {
       XStream xStream = new XStream(new DomDriver("UTF-8"));
       //XStream xStream = new XStream();
       xStream.alias("xml", textMessage.getClass());
       return xStream.toXML(textMessage);
   }

}

 如果用postman调用的需要这样:

springboot实现公众号接收回复消息和超过5秒被动回复消息

来源:https://blog.csdn.net/lianzhang861/article/details/124774884

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com