返回顶部
首页 > 资讯 > 后端开发 > Python >springboot实现公众号接收回复消息和超过5秒被动回复消息
  • 707
分享到

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

2024-04-02 19:04:59 707人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录1.首先第一步要接收微信消息,需要在公众号里设置与开发-基本配置里配置一下服务器配置2.配置好公众号以后,开始接收微信消息本次就是记录一下我的开发过程,不是教程,纯属自己做个笔记

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

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

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

这个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>

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

所以写个消息的实体类:

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;
 

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";
 
    
    public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
 
    
    public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
 
    
    public static final String EVENT_TYPE_CLICK = "CLICK";
 
    
    public static final String EVENT_TYPE_VIEW = "VIEW";
 
    
    public static final String EVENT_TYPE_LOCATION = "LOCATION";
 
    
    public static final String EVENT_TYPE_SCAN = "SCAN";
 
    
    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;
    }
 
    
    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调用的需要这样:

以上就是接收消息和被动回复消息,但是有个大坑,一开始我想着处理完消息在直接返回信息回去,但是处理时间总是超过5秒,每次超过5秒它就报一下服务出现故障,一共请求三次,三次都超时就给你报三次故障。

 后来客户不愿意报这玩意儿,就只好改成直接返回success再异步调用处理图片方法,处理完再用客服消息主动给用户发消息。

因为要处理图片花费的时间比较多,所以开个线程搞成异步调用处理图片再推送消息,这样的话直接返回字符串success

在controller里面写个方法接收一下,用@RequestBody 直接把发来的xml变成对象

@RequestMapping(value = "analyzeImg")
    @ResponseBody
    public String  analyzeImg(@RequestBody WxMessageImg wxMessageImg) throws Exception {
        //异步调用,先直接返回success,不然会显示程序异常
        new Thread(new Runnable() {
            public void run() {
                getImgData(wxMessageImg);
            }
        }).start();
        return "SUCCESS";
        //return null;
    }
public Object getImgData(WxMessageImg wxMessageImg){
 
    try {
         //忽略图片逻辑,直接闹个结果
         String resultStr="处理完图片返回的信息";
         String openid = wxMessageImg.getFromUserName(); //用户 openid
         postMessage(openid,resultStr);
 
    } catch (Exception e) {
        e.printStackTrace();
    }
 
    return null;
}

微信的破文档找个推送客户消息太费劲了,网上都到的基本都是发送模板消息,但我只是想发个文本消息呀!!

后来才找到发送客服消息的url是:https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=

发送模板消息的url是:https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=

官方接口介绍

8b9fb1d247a6e39d89120e536eecb336.jpg

发送文本信息

5a6b3017e06d600859751fea6a5041f7.jpg

所以我们需要的就是这个url和发送的文本格式,就这么简单几个值而已: 

public String postMessage(String openid,String content) throws Exception {
    //String access_token=WxMessageUtil.obtainAccessToken();
    //appid和appsecret为公众号里面的
    String tokenData = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
    // 返回的用户信息json字符串
    String result=HttpUtil.doGet(tokenData);
    System.out.println(result);
    JSONObject jsonObject = JSON.parseObject(result);
    //先获取access_token
    String access_token=String.valueOf(jsonObject.get("access_token"));
    System.out.println(access_token);
    //消息推送接口
    String path = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + access_token;
    JSONObject jsonData = new JSONObject();
    jsonData.put("touser", openid);
    jsonData.put("msgtype", "text");
    JSONObject text = new JSONObject();
    text.put("content",content);
    jsonData.put("text",text);
    System.out.println(jsonData);
    System.out.println(path);
    //HttpUtil.doPostJson(path, jsonData.toJSONString());
    HttpRequest.sendPost(path, jsonData.toJSONString());
    return "SUCCESS";
    //return null;
}

这样就能成功给用户异步回复消息,不会担心超过5秒报异常的问题了

package com.bomc.recordLife.util;
 
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
 
 
public class HttpRequest {
    
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "application/json, text/javascript, *
        
        //发送 POST 请求
       
		//(JSONObject)jsonarray[i]
    }
}

到此这篇关于SpringBoot实现公众号接收回复消息和超过5秒被动回复消息的文章就介绍到这了,更多相关springboot 公众号接收回复 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: springboot实现公众号接收回复消息和超过5秒被动回复消息

本文链接: https://lsjlt.com/news/149245.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • springboot实现公众号接收回复消息和超过5秒被动回复消息
    目录1.首先第一步要接收微信消息,需要在公众号里设置与开发-基本配置里配置一下服务器配置2.配置好公众号以后,开始接收微信消息本次就是记录一下我的开发过程,不是教程,纯属自己做个笔记...
    99+
    2024-04-02
  • nodejs微信公众号开发之如何实现自动回复各种消息
    这篇文章主要介绍了nodejs微信公众号开发之如何实现自动回复各种消息,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1. 被动回复用户消息当...
    99+
    2024-04-02
  • 详解nodejs微信公众号开发——4.自动回复各种消息
    上一篇文章:nodejs微信公众号开发——3.封装消息响应模块,实现了对消息接口的模块化处理,方便后期的使用,本篇文章将介绍微信公众号回复各种消息的功能实现,包括文本、图片、语音、视频、音乐、图文等。 注...
    99+
    2022-06-04
    详解 自动回复 公众
  • python自动化实现自动回复QQ消息
    目录前言1.需要安装的相关软件和python模块2. 连接手机3.测试是否连接成功4.代码实现5. 总结前言 近段时间,看了一下运用python实现app自动化的视频,觉得那上面的讲...
    99+
    2024-04-02
  • python自动化如何实现自动回复QQ消息
    这篇文章主要介绍了python自动化如何实现自动回复QQ消息,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.需要安装的相关软件和python模块1 安装client模块打开...
    99+
    2023-06-14
  • 微信小程序实现自动回复图片消息
    目录前提实现备注前提 小程序已经开通了“云开发”功能 在微信开发者工具中打开“云开发”,点“设置”,点击&ld...
    99+
    2023-01-17
    小程序自动回复 微信小程序自动回复 小程序自动回复图片
  • 微信公众平台开发中使用Java如何实现一个消息回复功能
    本篇文章给大家分享的是有关微信公众平台开发中使用Java如何实现一个消息回复功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。(一)回复文本消息在前面我们已经完成了对消息的分类...
    99+
    2023-05-31
    java 消息回复
  • Java微信公众平台开发(4) 回复消息的分类及实体的创建
    前面有说道对接收到微信服务器消息后对消息的分类,当时主要分为普通消息和事件消息,这里我们要讲述的是我们在给用户回复的消息类型,在这里也可以大致分为两类:一种为不需要上传资源到微信服务器的这里成为【普通消息回复】;还有一种需要上传资源到微信服...
    99+
    2023-05-31
    java 消息
  • 教你用python实现自动回复QQ消息(不到60行)
    目录前言1、需要安装的模块2、整体逻辑3、代码实现总结前言 最近在看测试相关的内容,发现自动化测试很好玩,就决定做一个自动回复QQ消息的脚本(我很菜) 1、需要安装的模块 这个自动化...
    99+
    2024-04-02
  • Python实现自动回复QQ消息功能的示例代码
    目录1、需要安装的模块2、整体逻辑3、代码实现最近在看测试相关的内容,发现自动化测试很好玩,就决定做一个自动回复QQ消息的脚本(我很菜) 1、需要安装的模块 这个自动化脚本需要用到3...
    99+
    2024-04-02
  • 微信公众平台开发中使用Java挺好实现一个多媒体消息回复功能
    微信公众平台开发中使用Java挺好实现一个多媒体消息回复功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。(一)素材接口图片上传按照之前我们的约定将接口请求的url写入到配置文...
    99+
    2023-05-31
    java 消息回复
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作