Java实现关注微信公众号和自动回复消息

依赖:


    dom4j
    dom4j
    1.6.1



    com.thoughtworks.xstream
    xstream
    1.4.11.1

关注公众号和自动回复, 共两个接口, 一个get, 一个post, 两个接口的url一样。

WeChatController

import com.ruoyi.ruoyiincome.wx.wechat.service.IWeChatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;

@Slf4j
@RestController
@RequestMapping("/wx")
public class WeChatController {


    @Autowired
    private IWeChatService weChatService;


    /**
     *  验证消息的确来自微信服务器
     *
     * @param signature    微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数
     * @param timestamp    时间戳
     * @param nonce        随机数
     * @param echostr      随机字符串
     * @return
     */
    @GetMapping(value = "/validateWeChatServer")
    public String validateWeChatServer(@RequestParam(name = "signature") String signature,
                                       @RequestParam(name = "timestamp") String timestamp,
                                       @RequestParam(name = "nonce") String nonce,
                                       @RequestParam(name = "echostr") String echostr) {
        return weChatService.validateWeChatServer(signature, timestamp, nonce, echostr);
    }

    /**
     * 接收用户消息并回复消息
     *
     * @param request       xml内容
     * @return              xml格式的字符串
     */
    @PostMapping("/validateWeChatServer")
    public String receiveMessage(HttpServletRequest request) {
        return weChatService.receiveMessage(request);
    }
}

WeChatServiceImpl

import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.ruoyiincome.wx.user.service.IResUserService;
import com.ruoyi.ruoyiincome.wx.vo.Article;
import com.ruoyi.ruoyiincome.wx.vo.NewsMessage;
import com.ruoyi.ruoyiincome.wx.vo.TextMessage;
import com.ruoyi.ruoyiincome.wx.wechat.service.IWeChatService;
import com.thoughtworks.xstream.XStream;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
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.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;


@Slf4j
@Service
public class WeChatServiceImpl implements IWeChatService {

    // 替换成你在微信公众平台设置的Token
    private static final String TOKEN = "your_wechat_token";


    /**
     *  验证消息的确来自微信服务器
     *
     * @param signature    微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数
     * @param timestamp    时间戳
     * @param nonce        随机数
     * @param echostr      随机字符串
     * @return
     */
    @Override
    public String validateWeChatServer(String signature, String timestamp, String nonce, String echostr) {
        // 将token、timestamp、nonce三个参数进行字典序排序
        String[] params = {TOKEN, timestamp, nonce};
        Arrays.sort(params);

        // 将三个参数字符串拼接成一个字符串进行sha1加密
        String encrypted = sha1Encode(params[0] + params[1] + params[2]);

        // 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
        if (encrypted.equals(signature)) {
            // 校验通过,返回echostr参数
            log.info("验证通过,消息的确来自微信服务器, 返回echostr参数: {}", echostr);
            return echostr;
        } else {
            // 校验失败,返回错误信息
            return "Invalid signature";
        }
    }


    /**
     * 接收用户消息并回复消息
     *
     * @param request       xml内容
     * @return              xml格式的字符串
     */
    @Override
    public String receiveMessage(HttpServletRequest request) {

        ServletInputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            HashMap map = new HashMap<>();
            SAXReader reader = new SAXReader();

            try {
                // 读取request输入流, 获取Document对象
                Document document = reader.read(inputStream);
                // 获取root节点
                Element root = document.getRootElement();
                // 获取所有的子节点
                List elements = root.elements();
                for (Element element : elements) {
                    map.put(element.getName(), element.getText());
                }
                log.info("接收到的用户消息: {}", map);
            } catch (DocumentException e) {
                e.printStackTrace();
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            // 关注用户, 保存到数据库
            SpringUtils.getBean(IResUserService.class).attentionMedia(map.get("FromUserName"));
            // 回复消息
            String message = getReplyTextMessage(map);
            log.info("回复消息: {}", message);
            return message;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getReplyTextMessage(HashMap map) {
        // 被动回复用户消息
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setMsgType("text");
        textMessage.setContent("【限时活动】 欢迎关注大师兄资源收益客栈! 已赠送90米粮(元), 点击右下角客官按钮即可提现");
        textMessage.setCreateTime(System.currentTimeMillis()/1000);

        // XStream将对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        String xml = xStream.toXML(textMessage);
        return xml;
    }

    private String sha1Encode(String input) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            byte[] hash = digest.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();

            for (byte b : hash) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }

            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}

TextMessage

import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;


/**
 * 公众号: 回复文本消息
 *
 */
@Data
@XStreamAlias("xml") // 别名
public class TextMessage {

    @XStreamAlias("ToUserName")
    private String toUserName;

    @XStreamAlias("FromUserName")
    private String fromUserName;

    @XStreamAlias("CreateTime")
    private long createTime;

    @XStreamAlias("MsgType")
    private String msgType;

    @XStreamAlias("Content")
    private String content;
}

在微信公众号的服务器配置中,首先需要编写Java代码来处理微信服务器的验证请求。以下是Java示例代码,然后我将为你提供启用服务器配置的步骤。(点击启用后微信服务器会调用该接口验证)

在上述代码中,/your_wechat_token是你在微信公众平台设置的Token。这个接口用于验证微信服务器配置的有效性。

接下来是如何启用服务器配置的步骤:

    1. 登录微信公众平台,进入公众号后台。

    2. 在左侧菜单中选择【开发】->【基本设置】。

    3. 找到【服务器配置】,点击右侧的【修改配置】按钮。

    4. 填入你的服务器配置信息:
        URL(服务器地址): 填写你的服务器地址,例如 https://xxx/wx/validateWeChatServer
        Token: 填写你在Java代码中设置的Token。
        EncodingAESKey: 如果你的消息加解密方式选择的是安全模式,需要填写。
    5. 将Java代码部署到你的服务器上,确保服务器可以被外部访问。

    6. 点击【保存并测试】,如果配置正确,你会看到【配置成功】的提示。

    7. 确认配置无误后,点击【启用】按钮,使服务器配置生效。

        完成上述步骤后,你的Java代码就能处理微信服务器的验证请求,服务器配置也会启用。接下来,你可以在代码中处理用户消息等业务逻辑。

Java实现关注微信公众号和自动回复消息_第1张图片

你可能感兴趣的:(公众号,微信,java)