Procházet zdrojové kódy

接收公众号消息

hsj před 1 měsícem
rodič
revize
6c15f1c972

+ 18 - 2
pom.xml

@@ -45,8 +45,24 @@
             <version>1.2.83</version>
         </dependency>
         <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-mail</artifactId>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-xml</artifactId>
+            <version>2.15.3</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-xml</artifactId>
+        </dependency>
+        <!-- Apache Commons 工具类 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+
+        <!-- 加密解密工具 -->
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
         </dependency>
     </dependencies>
 

+ 36 - 0
src/main/java/top/husj/husj_wx/controller/WeChatController.java

@@ -0,0 +1,36 @@
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import top.husj.husj_wx.entity.model.WeChatMsg;
+
+@RestController
+@RequestMapping("/wechat")
+public class WeChatController {
+
+    private final String TOKEN = "你设置的Token";
+
+    // 1. 微信后台验证 URL 时使用 (GET)
+    @GetMapping("/callback")
+    public String checkSignature(String signature, String timestamp, String nonce, String echostr) {
+        // 这里需要按照微信算法:将token、timestamp、nonce字典排序并SHA1加密,对比signature
+        // 为了演示快速上手,这里直接返回 echostr(正式环境必须校验!)
+        return echostr;
+    }
+
+    // 2. 接收用户消息 (POST)
+    @PostMapping(value = "/callback", consumes = MediaType.TEXT_XML_VALUE, produces = MediaType.TEXT_XML_VALUE)
+    public String handleMessage(@RequestBody WeChatMsg msg) {
+        System.out.println("收到来自用户 " + msg.getFromUserName() + " 的消息:" + msg.getContent());
+
+        // 构造被动回复(同样是XML)
+        return String.format(
+                "<xml>" +
+                        "<ToUserName><![CDATA[%s]]></ToUserName>" +
+                        "<FromUserName><![CDATA[%s]]></FromUserName>" +
+                        "<CreateTime>%d</CreateTime>" +
+                        "<MsgType><![CDATA[text]]></MsgType>" +
+                        "<Content><![CDATA[已收到你的消息:%s]]></Content>" +
+                        "</xml>",
+                msg.getFromUserName(), msg.getToUserName(), System.currentTimeMillis() / 1000, msg.getContent()
+        );
+    }
+}

+ 18 - 0
src/main/java/top/husj/husj_wx/entity/model/WeChatMsg.java

@@ -0,0 +1,18 @@
+package top.husj.husj_wx.entity.model;
+
+import lombok.Data;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+@Data
+@JacksonXmlRootElement(localName = "xml")
+public class WeChatMsg {
+    @JacksonXmlProperty(localName = "ToUserName")
+    private String toUserName;
+    @JacksonXmlProperty(localName = "FromUserName")
+    private String fromUserName;
+    @JacksonXmlProperty(localName = "Content")
+    private String content;
+    @JacksonXmlProperty(localName = "MsgType")
+    private String msgType;
+}

+ 16 - 0
src/main/java/top/husj/husj_wx/utils/SignUtil.java

@@ -0,0 +1,16 @@
+package top.husj.husj_wx.utils;
+
+import java.util.Arrays;
+
+public class SignUtil {
+    public static boolean checkSignature(String token, String signature, String timestamp, String nonce) {
+        String[] arr = new String[]{token, timestamp, nonce};
+        Arrays.sort(arr); // 字典序排序
+        StringBuilder content = new StringBuilder();
+        for (String s : arr) content.append(s);
+        
+        // 使用Apache Commons Codec或自定义SHA1加密
+        String temp = DigestUtils.sha1Hex(content.toString());
+        return temp.equalsIgnoreCase(signature);
+    }
+}

+ 1 - 1
src/main/resources/application.yml

@@ -3,4 +3,4 @@ spring:
     name: husj-wx
 server:
   servlet:
-    context-path: /wx
+    context-path: /wechat