准备

  • 注册微信公众号:微信公众平台;或者使用申请测试账号来演示:测试账号申请地址
  • 能够使用外网访问的地址:这里使用的是内网穿透工具花生壳,点击跳转

配置接口

提示:等接口写好后在进行接口配置;配置保存时,微信官方会发送请求到配置的接口进行验证,只有通过验证才能配置成功;

代码实现

依赖

<!-- XML 文件读写 -->
<dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.0.0</version>
</dependency>

编写认证接口,同时也是接收消息接口(GET/POST)

package com.andon.wxPush.web;import com.alibaba.fastjson.JSONObject;
import com.andon.entity.an.AnCurrentAndon;
import com.andon.wxPush.service.WxReceiveMsg;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;@Slf4j
@Api(description = "微信公众号接口")
@RestController
@RequestMapping("/wx/officialAccount")
public class WxGzhController {@Resourceprivate WxReceiveMsg wxReceiveMsg;/*** 认证接收微信公众号的消息(GET请求进行认证/POST请求进行接收消息并返回)*/@RequestMapping("/signReceiveWxGzhMsg")public String checkValid(String signature, String timestamp, String nonce, String echostr, HttpServletRequest req) {String requestMethod = req.getMethod();if (requestMethod.equals("POST")) { // 处理 POST 请求Map<String, String> msgMap = wxReceiveMsg.parseXmlData2Map(req);System.out.println(msgMap);String s = wxReceiveMsg.receiveMessage(msgMap);return s;} else if (requestMethod.equals("GET")) { // 处理 GET 请求log.info("signature: {} nonce: {} echostr: {} timestamp: {}", signature, nonce, echostr, timestamp);return wxReceiveMsg.checkSignature(signature, timestamp, nonce) ? echostr : "校验失败";} else {return "不是 GET 和 POST";}}
}

WxReceiveMsg

package com.andon.wxPush.service;import javax.servlet.http.HttpServletRequest;
import java.util.Map;public interface WxReceiveMsg {boolean checkSignature(String signature, String timestamp, String nonce);Map<String, String> parseXmlData2Map(HttpServletRequest req);String receiveMessage(Map<String, String> param);
}

WxReceiveMsgImpl

package com.andon.wxPush.service.impl;import com.andon.wxPush.service.WxReceiveMsg;
import com.andon.wxPush.utils.AesException;
import com.andon.wxPush.utils.SHA1;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.stereotype.Service;import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;@Service
public class WxReceiveMsgImpl implements WxReceiveMsg {private static final String TOKEN = "Eric";/*** 验证签名* @param signature* @param timestamp* @param nonce* @return*/@Overridepublic boolean checkSignature(String signature, String timestamp, String nonce) {//进行sha1加密String temp = null;try {temp = SHA1.getSHA1(TOKEN, timestamp, nonce);} catch (Exception e) {e.printStackTrace();}//与微信提供的signature进行匹对return signature.equals(temp);}/*** 解析xml格式数据转为map格式* @param req* @return*/@Overridepublic Map<String, String> parseXmlData2Map(HttpServletRequest req) {HashMap<String, String> msgMap = new HashMap<>();try {ServletInputStream inputStream = req.getInputStream();// dom4j 用于读取 XML 文件输入流的类SAXReader saxReader = new SAXReader();// 读取 XML 文件输入流, XML 文档对象Document document = saxReader.read(inputStream);// XML 文件的根节点Element root = document.getRootElement();// 所有的子节点List<Element> childrenElement = root.elements();for (Element element : childrenElement) {msgMap.put(element.getName(), element.getStringValue());}} catch (Exception e) {e.printStackTrace();}return msgMap;}/*** 接收消息,判断消息类型,并根据关键词进行回复* @param param* @return*/@Overridepublic String receiveMessage(Map<String, String> param) {String content = "";try {//消息类型String msgType = param.get("MsgType");switch(msgType){case "text" :       //普通文本类型,例如用户发送:javacontent = this.keyWordMsgTip(param);break;default:content = "success";}} catch (Exception e) {e.printStackTrace();}return content;}/*** 处理关键字搜索事件* 图文消息个数;当用户发送文本、图片、语音、视频、图文、地理位置这六种消息时,开发者只能回复1条图文消息;其余场景最多可回复8条图文消息* @param param* @return*/private String keyWordMsgTip(Map<String, String> param) {String fromusername = param.get("FromUserName");String tousername = param.get("ToUserName");String content = param.get("Content");//单位为秒,不是毫秒Long createTime = new Date().getTime() / 1000;StringBuffer text = new StringBuffer();//这个判断是为靓仔专属设定的if("java".equals(content)){//一次只能返回一个//标题String title = "Java";//描述String description = "java详情";//图片String PicUrl = "https://amaxchina.picp.vip/system/api/resourceFile/1679982783397_1_UserAvatar_cropped.png";//链接地址String url = null;try {String redirect_uri = URLEncoder.encode("https://amaxchina.picp.vip/#/authentication", "UTF-8");url = "https://java.com/";} catch (UnsupportedEncodingException e) {e.printStackTrace();}StringBuffer articles = new StringBuffer();articles.append("<item>");articles.append("<Title><![CDATA["+title+"]]></Title>");articles.append("<Description><![CDATA["+description+"]]></Description>");articles.append("<PicUrl><![CDATA["+PicUrl+"]]></PicUrl>");articles.append("<Url><![CDATA["+url+"]]></Url>");articles.append("</item>");text.append("<xml>");text.append("<ToUserName><![CDATA["+fromusername+"]]></ToUserName>");text.append("<FromUserName><![CDATA["+tousername+"]]></FromUserName>");text.append("<CreateTime><![CDATA["+createTime+"]]></CreateTime>");text.append("<MsgType><![CDATA[news]]></MsgType>");text.append("<ArticleCount><![CDATA[1]]></ArticleCount>");text.append("<Articles>");text.append(articles);text.append("</Articles>");text.append("</xml>");}return text.toString();}
}

SHA1

package com.andon.wxPush.utils;/*** 对公众平台发送给公众账号的消息加解密示例代码.** @copyright Copyright (c) 1998-2014 Tencent Inc.*/// ------------------------------------------------------------------------import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;/*** SHA1 class** 计算公众平台的消息签名接口.*/
public class SHA1 {/*** 用SHA1算法验证Token** @param token     票据* @param timestamp 时间戳* @param nonce     随机字符串* @return 安全签名* @throws AesException*/public static String getSHA1(String token, String timestamp, String nonce) throws AesException {try {String[] array = new String[]{token, timestamp, nonce};StringBuffer sb = new StringBuffer();// 字符串排序Arrays.sort(array);for (int i = 0; i < 3; i++) {sb.append(array[i]);}String str = sb.toString();// SHA1签名生成MessageDigest md = MessageDigest.getInstance("SHA-1");md.update(str.getBytes());byte[] digest = md.digest();StringBuffer hexstr = new StringBuffer();String shaHex = "";for (int i = 0; i < digest.length; i++) {shaHex = Integer.toHexString(digest[i] & 0xFF);if (shaHex.length() < 2) {hexstr.append(0);}hexstr.append(shaHex);}return hexstr.toString();} catch (Exception e) {e.printStackTrace();throw new AesException(AesException.ComputeSignatureError);}}
}

AesException

package com.andon.wxPush.utils;@SuppressWarnings("serial")
public class AesException extends Exception {public final static int OK = 0;public final static int ValidateSignatureError = -40001;public final static int ParseXmlError = -40002;public final static int ComputeSignatureError = -40003;public final static int IllegalAesKey = -40004;public final static int ValidateAppidError = -40005;public final static int EncryptAESError = -40006;public final static int DecryptAESError = -40007;public final static int IllegalBuffer = -40008;//public final static int EncodeBase64Error = -40009;//public final static int DecodeBase64Error = -40010;//public final static int GenReturnXmlError = -40011;private int code;private static String getMessage(int code) {switch (code) {case ValidateSignatureError:return "签名验证错误";case ParseXmlError:return "xml解析失败";case ComputeSignatureError:return "sha加密生成签名失败";case IllegalAesKey:return "SymmetricKey非法";case ValidateAppidError:return "appid校验失败";case EncryptAESError:return "aes加密失败";case DecryptAESError:return "aes解密失败";case IllegalBuffer:return "解密后得到的buffer非法";
//      case EncodeBase64Error:
//          return "base64加密错误";
//      case DecodeBase64Error:
//          return "base64解密错误";
//      case GenReturnXmlError:
//          return "xml生成失败";default:return null; // cannot be}}public int getCode() {return code;}AesException(int code) {super(getMessage(code));this.code = code;}
}

效果

springBoot 实现微信公众号消息自动回复相关推荐

  1. 公众号自动回复需要服务器,关于微信公众号消息自动回复5秒限制问题的解决方案...

    一般申请了公众号的想要快速部署投入应用的,可以使用微信公众号平台自带的消息自动回复等功能,但是不能对用户发来的消息进行处理,所以我们会使用程序对接微信公众号进行微信公众号开发. 于是大家可能都会遇到这 ...

  2. 【微信开发第二章】SpringBoot实现微信公众号普通消息和模板消息回复

    前言 在进行微信公众号业务开发的时候,微信公众号的消息回复是非常重要的一环,而微信公众号消息回复分为:普通消息自动回复和模板消息回复.该篇文章会先使用微信测试工具过一遍流程,再使用代码进行实现,并且每 ...

  3. SpringBoot搭建微信公众号后台(一):消息接收与响应

    关注作者,更多动态实时掌握,微信公众号:隔壁的程序员 上一篇我们经过接口验证,已经可以与微信的服务器进行通信,错过的可以通过下面链接来进行回顾,这一篇就来实现一个基本的消息接收与响应. SpringB ...

  4. 怎样设置微信公众号延迟自动回复消息带超链接

    为了实现的微信公众号延迟自动回复消息带超链接需要,第三方平台微号帮提供了粉丝对话定时推送功能实现,可以让微信公众号自动回复消息带超链接,粉丝点击链接可以进入其他平台,设置自动回复消息添加链接,注意先在 ...

  5. SpringBoot开发微信公众号

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 在讲微信公众号开发之前,先来大概了解一下微信公众号.微信公 ...

  6. php 公众号验证回调方法_微信公众号关键词自动回复设置方法!

    什么是公众号关键词自动回复? 在微信公众号平台设置关键词自动回复,可以通过添加规则,关注/订阅的用户发送的消息内容如果是你设置的关键字,即可以实现自动回复预先设置好的内容. 关键字自动回复设置方法: ...

  7. 微信公众号关键词自动回复大全

    作为公众号运营者,我们都知道在公众号与用户的聊天界面,是有一个关键词自动回复功能的,但是最近我发现了一个小程序,是仿照这个自动回复功能,但是其实是设置在文章中的,那么在文章中有了这个功能实际上也大大提 ...

  8. 【微信开发第一章】SpringBoot实现微信公众号创建菜单,同步菜单功能

    前言 在进行微信公众号业务开发的时候,微信公众号的自定义菜单是非常重要的一环,该篇文章会先使用微信测试工具过一遍流程,再使用代码进行实现,争取看过的小伙伴都能够实现,创建公众号菜单和代码同步公众号菜单 ...

  9. SpringBoot搭建微信公众号后台(零):服务搭建与接口验证

    关注作者,更多动态实时掌握,微信公众号:隔壁的程序员 前言:从这篇开始小王子将开始一个新的系列内容,从零开始搭建自己的微信公众号后台.内容大致规划为:环境篇,包括用到的工具安装,破解,配置:基础篇,主 ...

最新文章

  1. 整数展示分数和整形数的四则运算
  2. 毛坦厂中学是“高考工厂”?白岩松:我做不出嘲讽它的事情!
  3. 初学者先学python语音好吗_献给Python初学者 零基础学习Python能学会吗
  4. Swagger原理解析
  5. clion开发qt项目QtGui/qcolor.h: In construconstexpr QColor::QColor(int, int, int, int)’:ctor ‘1073741515
  6. WiFi 扫描处理过程
  7. 楚留香ai识别人脸_【专利解密】商汤科技:AI加持人脸识别
  8. Ubuntu 下安装 QQ
  9. unity3d_打飞碟
  10. 手写多图片合并成一张图片功能插件(水印合成)
  11. 每个男人心中都有一段《西西里的美丽传说》
  12. 金庸群侠X版 会议纪要
  13. vivo陷全国手机行业反垄断第一案
  14. set_sql_trace_in_session PLS-00201
  15. 快手sig3,did设备注册算法
  16. 编程方法论/架构设计/模式相关转载链接汇总
  17. 独家揭开几项神秘SEO技术的猪八戒面纱
  18. leetcode_hot10-
  19. iphone原彩显示对眼睛好吗_iphone的原彩显示有什么用吗
  20. 迈德威视工业相机入门( 基于 Windows 系统 + VS2019 + OpenCV 4.x.x )

热门文章

  1. 云计算中的计算虚拟化的发展史
  2. win10系统崩溃怎么修复_小编调解 win10系统wifi保护器防蹭网的修复教程 -win10使用教程...
  3. 将整数k转换成实数python表达式_在混合类型表达式中python自动转换intlongfloat例如.ppt...
  4. 名人大咖,那些你想不到的大佬程序员,有几个是你的爱豆?
  5. 常见图像采集卡驱动、图像采集软件、开发例程下载地址
  6. VVC学习之一:VVC/H.266的简介及VTM的使用方法
  7. 6.S081-Lab3
  8. 斑马888-tt条码打印开发
  9. 虚拟服务器 规则名称,虚拟主机伪静态规则怎么添加
  10. 5个你应该知道的建站平台