微信公众号服务器自定义回复

发布时间:2023年12月27日

1.效果图


2.maven

        <!--公众号工具类-->
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-mp</artifactId>
            <version>4.1.0</version>
        </dependency>

3.代码

package com.kenick.mp.controller;

import com.kenick.mp.config.WxMpUtil;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.builder.outxml.TextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @description 微信公众号
 * @date 2023/12/27
 */
@Controller
@RequestMapping("/mp")
public class WxMpController {

    private final static Logger logger = LoggerFactory.getLogger(WxMpController.class);

    @Resource
    private WxMpUtil wxMpUtil;

    /**
     * 与微信服务器保持心跳,同时进行内容校验
     * 必须为get方式
     *
     * @param signature 心跳内容签名,微信服务器配置的token+timestamp+nonce进行sha1加密后的密文
     * @param timestamp 时间戳字符串
     * @param nonce     随机数
     * @param echostr   随机内容,回复时要保持一致
     * @return 校验通过回复对方发送过来的内容, 否则回复空字符串
     */
    @ResponseBody
    @RequestMapping("/heartbeat")
    public String heartbeat(@RequestParam("signature") String signature,
                            @RequestParam("timestamp") String timestamp,
                            @RequestParam("nonce") String nonce,
                            @RequestParam("echostr") String echostr) {
        logger.debug("WxMpController.heartbeat,{},{},{},{}", signature, timestamp, nonce, echostr);
        try {
            if (wxMpUtil.checkSignature("微信配置的token,不是accessToken", timestamp, nonce, signature)) {
                return echostr;
            }
        } catch (Exception e) {
            logger.error("公众号心跳异常", e);
        }
        return "";
    }

    /**
     * 接收微信公众号发送过来的消息,与心跳接口路径一样
     * 必须为post方式
     *
     * @return 无自定义回复返回success, 表示服务器已收到;自定义回复xml格式数据
     */
    @ResponseBody
    @PostMapping(value = "/heartbeat")
    public String receive(HttpServletRequest request) {
        try {
            WxMpXmlMessage wxMpXmlMessage = WxMpXmlMessage.fromXml(request.getInputStream());
            logger.debug("WxMpController.receive,{}", wxMpXmlMessage);
            if (wxMpXmlMessage != null && "text".equals(wxMpXmlMessage.getMsgType())) {
                String toUserName = wxMpXmlMessage.getFromUser();
                String fromUserName = wxMpXmlMessage.getToUser();
                String content = wxMpXmlMessage.getContent();
                logger.debug("toUserName:{},fromUserName:{},content:{}", toUserName, fromUserName, content);

                String replyXml = new TextBuilder().fromUser(fromUserName)
                        .toUser(toUserName)
                        .content("replay:" + content + ",\n链接:https://www.baidu.com")
                        .build().toXml();
                logger.debug("回应的xml:{}", replyXml);
                return replyXml;
            }
        } catch (Exception e) {
            logger.error("接收消息异常", e);
        }
        return "success";
    }

    /**
     * 获取微信公众号的accessToken
     *
     * @param passwd 简单的自定义密码验证
     */
    @ResponseBody
    @RequestMapping("/getAccessToken")
    public String getAccessToken(@RequestParam(value = "passwd", required = false) String passwd) {
        logger.debug("WxMpController.getAccessToken");
        try {
            if ("kenick".equals(passwd)) {//简单的密码验证
                return wxMpUtil.getAccessToken();
            }
        } catch (Exception e) {
            logger.error("getAccessToken异常", e);
        }
        return "";
    }

}
package com.kenick.mp.config;

import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @description 微信公众号工具类
 * @date 2023/12/27
 */
@Component
public class WxMpUtil {

    private final static Logger logger = LoggerFactory.getLogger(WxMpUtil.class);

    //微信公众号id
    @Value("${wechat.mpAppId}")
    private String mpAppId;

    //微信公众号密码
    @Value("${wechat.mpAppSecret}")
    private String mpAppSecret;

    //微信公众号工具服务
    private static WxMpService wxMpService;

    //获取mp服务
    public WxMpService getMpService() {
        if (wxMpService != null) {
            return wxMpService;
        }
        WxMpDefaultConfigImpl wxMpConfigStorage = new WxMpDefaultConfigImpl();
        wxMpConfigStorage.setAppId(mpAppId);
        wxMpConfigStorage.setSecret(mpAppSecret);
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage);
        return wxMpService;
    }

    //通过WxMpService工具获取accessToken
    public String getAccessToken() {
        try {
            return getMpService().getAccessToken();
        } catch (Exception e) {
            logger.error("获取accessToken异常", e);
        }
        return "";
    }

    //校验心跳消息签名
    public boolean checkSignature(String token, String timestamp, String nonce, String signature) {
        try {
            return signature.equals(gen(token, timestamp, nonce));
        } catch (Exception e) {
            logger.error("校验签名异常", e);
        }
        return false;
    }

    //sha1加密
    public String gen(String... arr) {
        if (StringUtils.isAnyEmpty(arr)) {
            throw new IllegalArgumentException("非法请求参数,有部分参数为空 : " + Arrays.toString(arr));
        } else {
            Arrays.sort(arr);
            StringBuilder sb = new StringBuilder();
            String[] var2 = arr;
            int var3 = arr.length;

            for (int var4 = 0; var4 < var3; ++var4) {
                String a = var2[var4];
                sb.append(a);
            }

            return DigestUtils.sha1Hex(sb.toString());
        }
    }

}
wechat.mpAppId=xxxx
wechat.mpAppSecret=xxxx

文章来源:https://blog.csdn.net/leadseczgw01/article/details/135250106
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。