杰瑞科技汇

Java开发微信公众平台教程从哪开始学?

Java 开发微信公众平台完整教程

微信公众平台为开发者提供了丰富的接口,让我们可以构建强大的自定义服务,如自动回复、菜单管理、用户管理、模板消息等,本教程将手把手教你如何使用 Java (Spring Boot) 来开发一个微信公众号。

Java开发微信公众平台教程从哪开始学?-图1
(图片来源网络,侵删)

目录

  1. 第一部分:准备工作

    • 1 注册并配置公众号
    • 2 获取开发者凭证
    • 3 配置服务器信息(服务器地址 & Token)
    • 4 开发环境准备
  2. 第二部分:核心代码实现

    • 1 创建 Spring Boot 项目
    • 2 实现服务器验证(Token 验证)
    • 3 接收和解析用户消息
    • 4 实现自动回复
    • 5 创建自定义菜单
    • 6 发送模板消息
  3. 第三部分:部署与上线

    • 1 准备服务器
    • 2 使用 Nginx 反向代理
    • 3 使用 HTTPS (必备)
    • 4 部署应用
  4. 第四部分:进阶与总结

    Java开发微信公众平台教程从哪开始学?-图2
    (图片来源网络,侵删)
    • 1 获取用户 OpenID
    • 2 推荐使用成熟的 SDK
    • 3 学习资源

第一部分:准备工作

在开始编码之前,我们必须完成微信官方的配置工作。

1 注册并配置公众号

  1. 访问 微信公众平台
  2. 使用你的个人身份证号或企业资质进行注册,对于学习和开发,推荐注册 订阅号,流程相对简单。
  3. 登录后,在后台找到 “设置与开发” -> “基本配置”

2 获取开发者凭证

在“基本配置”页面,你会看到:

  • AppID (应用ID): 公众号的唯一标识。
  • AppSecret (应用密钥): 用于获取 Access Token 的密钥,请务必保密

3 配置服务器信息(服务器地址 & Token)

这是最关键的一步,它将你的公众号和你的后端服务连接起来。

  1. 在“基本配置”页面,点击 “配置” 按钮。

    Java开发微信公众平台教程从哪开始学?-图3
    (图片来源网络,侵删)
  2. 填写以下信息:

    • URL (服务器地址): 你的 Java Web 应用对外访问的地址。https://yourdomain.com/wechat
    • Token (令牌): 可以任意填写,如 myWechatToken123,这个 Token 将用于微信服务器验证你的身份。
    • EncodingAESKey (消息加解密密钥): 可以随机生成,用于消息的安全传输,如果暂时不需要,可以留空。
    • 消息加解密方式: 选择 “安全模式”“兼容模式”,开发阶段可以选择“明文模式”,但生产环境务必选择安全模式。
  3. 点击 “提交”,微信服务器会向你的 URL 发送一个 GET 请求,你需要编写代码来响应这个请求以完成验证,如果验证成功,配置才会生效。

4 开发环境准备

  • JDK: 推荐 JDK 8 或更高版本。
  • IDE: IntelliJ IDEA 或 Eclipse。
  • 构建工具: Maven 或 Gradle。
  • Web 框架: Spring Boot (强烈推荐,可以极大简化开发)。
  • HTTP 客户端: 用于调用微信 API,如 OkHttpApache HttpClient
  • JSON 库: 如 JacksonGson

第二部分:核心代码实现

我们将使用 Spring Boot 来快速搭建项目。

1 创建 Spring Boot 项目

  1. 访问 Spring Initializr
  2. 填写项目信息:
    • Project: Maven
    • Language: Java
    • Spring Boot: 选择一个稳定版本 (如 2.7.x 或 3.x.x)
    • Project Metadata: Group, Artifact, Name 等。
    • Dependencies: 添加 Spring Web
  3. 点击 "Generate" 下载项目压缩包,并用 IDE 打开。

2 实现服务器验证(Token 验证)

当你在公众号后台提交 URL 时,微信服务器会发送如下格式的 GET 请求:

https://yourdomain.com/wechat?signature=ASDFGHJKL&timestamp=1234567890&nonce=987654321&echostr=hello_world

你需要根据 signature, timestamp, nonce 和你在后台配置的 Token 来进行验证,验证逻辑如下:

  1. Token, timestamp, nonce 三个参数进行字典序排序。
  2. 将三个参数字符串拼接成一个字符串进行 SHA1 加密。
  3. 将加密后的字符串与 signature 对比,如果相同,则请求来自微信,返回 echostr 即可。

代码实现:

创建一个 Controller 来处理 /wechat 路径的请求。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@RestController
@RequestMapping("/wechat")
public class WeChatController {
    // 在公众号后台配置的 Token
    private static final String TOKEN = "myWechatToken123";
    @GetMapping
    public void validate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        if (isWeChatRequest(signature, timestamp, nonce)) {
            // 验证成功,返回 echostr
            response.getWriter().print(echostr);
        } else {
            // 验证失败
            response.getWriter().print("Invalid request");
        }
    }
    private boolean isWeChatRequest(String signature, String timestamp, String nonce) {
        // 1. 将 token, timestamp, nonce 三个参数进行字典序排序
        List<String> params = Arrays.asList(TOKEN, timestamp, nonce);
        Collections.sort(params);
        // 2. 将三个参数字符串拼接成一个字符串
        String paramStr = String.join("", params);
        // 3. 进行 SHA1 加密
        String encryptedStr = sha1(paramStr);
        // 4. 开发者获得加密后的字符串可与 signature 对比
        return encryptedStr != null && encryptedStr.equals(signature);
    }
    private String sha1(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            byte[] digestBytes = digest.digest(str.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : digestBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}

测试: 将你的项目运行起来,确保外网可以访问 https://yourdomain.com/wechat,然后在公众号后台点击“提交”,如果成功,说明服务器验证已经完成。

3 接收和解析用户消息

当用户与公众号互动时,微信服务器会向你的 URL 发送一个 POST 请求,请求体是 XML 格式的消息,我们需要创建一个接口来处理 POST 请求。

用户发送文本消息的 XML 示例:

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1348831860</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[this is a test]]></Content>
  <MsgId>1234567890123456</MsgId>
</xml>

代码实现:

  1. 创建消息实体类:

    import javax.xml.bind.annotation.XmlRootElement;
    @XmlRootElement
    public class WeChatMessage {
        private String ToUserName;
        private String FromUserName;
        private long CreateTime;
        private String MsgType;
        private String Content;
        private long MsgId;
        // Getters and Setters...
    }
  2. 修改 Controller 处理 POST 请求:

    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    // ... imports ...
    @RestController
    @RequestMapping("/wechat")
    public class WeChatController {
        // ... GET 方法 ...
        @PostMapping
        public String handlePost(HttpServletRequest request) throws Exception {
            // 1. 获取请求体中的 XML 数据
            String xmlData = IOUtils.toString(request.getInputStream(), "UTF-8");
            // 2. 解析 XML
            Document document = DocumentHelper.parseText(xmlData);
            Element root = document.getRootElement();
            String fromUser = root.element("FromUserName").getStringValue();
            String toUser = root.element("ToUserName").getStringValue();
            String msgType = root.element("MsgType").getStringValue();
            String content = root.element("Content").getStringValue();
            // 3. 根据消息类型处理
            if ("text".equals(msgType)) {
                // 用户发送的是文本,进行回复
                String replyContent = "你发送的是: " + content;
                return buildTextReply(toUser, fromUser, replyContent);
            }
            // 其他消息类型...
            return "success"; // 返回 success 表示微信服务器不再重发
        }
        private String buildTextReply(String toUser, String fromUser, String content) {
            // 构造回复消息的 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>",
                toUser, fromUser, System.currentTimeMillis() / 1000, content
            );
        }
    }

    注意:这里使用了 dom4jjackson 来解析 XML 会更方便。

4 实现自动回复

上面的 handlePost 方法已经实现了最简单的文本自动回复,你可以根据 content 的内容,实现更复杂的逻辑,比如关键词回复、菜单点击回复等。

5 创建自定义菜单

自定义菜单不是通过接收消息来触发的,而是需要你主动调用微信的 API 来创建。

步骤:

  1. 获取 access_token
  2. 调用创建菜单的 API。

获取 Access Token

access_token 是调用所有接口的凭证,有效期 2 小时,需要缓存起来。

import org.springframework.web.client.RestTemplate;
public class WeChatApiService {
    private static final String APPID = "你的AppID";
    private static final String APPSECRET = "你的AppSecret";
    private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
    private RestTemplate restTemplate;
    // 使用缓存存储 token,例如用 Caffeine 或 Guava Cache
    // private Cache<String, String> tokenCache;
    public String getAccessToken() {
        // 1. 先从缓存中获取
        // String token = tokenCache.getIfPresent("access_token");
        // if (token != null) {
        //     return token;
        // }
        // 2. 缓存中没有,则调用接口获取
        String url = String.format(TOKEN_URL, APPID, APPSECRET);
        AccessTokenResponse response = restTemplate.getForObject(url, AccessTokenResponse.class);
        // 3. 存入缓存
        // tokenCache.put("access_token", response.getAccessToken());
        return response.getAccessToken();
    }
    // 响应实体
    public static class AccessTokenResponse {
        private String access_token;
        private int expires_in;
        // getters and setters...
    }
}

调用创建菜单 API

菜单的配置是一个复杂的 JSON 对象,你可以先在微信公众平台“自定义菜单”工具里生成好 JSON。

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
public void createMenu() {
    String accessToken = getAccessToken();
    String menuUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + accessToken;
    // 菜单的 JSON 配置
    String menuJson = "{...}"; // 你的菜单 JSON
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<String> entity = new HttpEntity<>(menuJson, headers);
    restTemplate.postForEntity(menuUrl, entity, String.class);
}

6 发送模板消息

模板消息用于在特定场景下向用户发送重要通知,如订单确认、物流更新等。

步骤:

  1. 在公众号后台“模板消息”中找到并选用模板。
  2. 获取用户的 openid
  3. 调用发送模板消息 API。

API 调用示例:

public void sendTemplateMessage(String openid) {
    String accessToken = getAccessToken();
    String templateUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
    // 构造请求体 JSON
    String requestJson = String.format(
        "{\"touser\":\"%s\",\"template_id\":\"你的模板ID\",\"data\":{\"first\":{\"value\":\"恭喜你购买成功!\"},\"keyword1\":{\"value\":\"20251228\"},\"keyword2\":{\"value\":\"88.88\"},\"remark\":{\"value\":\"欢迎再次购买!\"}}}",
        openid
    );
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<String> entity = new HttpEntity<>(requestJson, headers);
    restTemplate.postForEntity(templateUrl, entity, String.class);
}

第三部分:部署与上线

你的应用需要部署在一个有公网 IP 的服务器上,并且支持 HTTPS。

1 准备服务器

  • 云服务器: 阿里云、腾讯云、华为云等,选择一个你熟悉的。
  • 系统: CentOS 或 Ubuntu。
  • 环境: 安装 JDK, Maven, Git。

2 使用 Nginx 反向代理

直接将 Spring Boot 应用(默认 8080 端口)暴露给公网不安全,使用 Nginx 作为反向代理,可以隐藏后端端口,并实现负载均衡。

Nginx 配置示例 (/etc/nginx/conf.d/wechat.conf):

server {
    listen 80;
    server_name yourdomain.com; # 你的域名
    location /wechat {
        proxy_pass http://127.0.0.1:8080; # 代理到你的 Spring Boot 应用
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

3 使用 HTTPS (必备)

微信服务器要求你的回调 URL 必须是 https 开头的。

  1. 域名备案: 如果你的服务器在国内,域名必须先备案。
  2. 购买/申请 SSL 证书:
    • 免费: Let's Encrypt (推荐)。
    • 付费: 各大云服务商都提供。
  3. 配置 Nginx:
server {
    listen 443 ssl;
    server_name yourdomain.com;
    ssl_certificate     /path/to/your/cert.pem;      # 证书文件
    ssl_certificate_key /path/to/your/cert.key;      # 私钥文件
    location /wechat {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
# 将 HTTP 请求重定向到 HTTPS
server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$host$request_uri;
}

4 部署应用

  1. 将你的 Spring Boot 项目打包成 JAR 包:mvn clean package
  2. 将 JAR 文件上传到服务器。
  3. 使用 nohup 命令让它在后台运行:
    nohup java -jar your-app.jar > app.log 2>&1 &
  4. 可以使用 supervisorsystemd 来管理进程,实现开机自启和自动重启。

第四部分:进阶与总结

1 获取用户 OpenID

当用户关注公众号或与公众号交互时,消息中会包含 FromUserName,这个值就是用户的 OpenID,是用户在公众号下的唯一标识。请务必妥善保存,有了 OpenID,你才能给特定用户发送模板消息。

2 推荐使用成熟的 SDK

手动处理 XML、调用 API、管理 access_token 等过程非常繁琐,容易出错,强烈建议使用成熟的第三方 SDK,它们封装了所有细节。

  • me.chanjar:weixin-java: (推荐) 功能非常全面,文档和社区都很好。
  • WxJava: 另一个流行的 Java 微信开发 SDK。

使用 weixin-java 的示例:

<!-- Maven 依赖 -->
<dependency>
    <groupId>me.chanjar</groupId>
    <artifactId>weixin-java-mp</artifactId>
    <version>最新版本号</version>
</dependency>
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
// 初始化 WxMpService
WxMpService wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(new WxMpInMemoryConfigStorage());
wxMpService.getWxMpConfigStorage().setAppid("yourAppId");
wxMpService.getWxMpConfigStorage().setSecret("yourAppSecret");
// 设置消息路由
WxMpMessageRouter router = new WxMpMessageRouter(wxMpService);
router.rule()
    .msgType("text")
    .content("你好")
    .handler(new WxMpMessageHandler() {
        @Override
        public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, WxMpService wxMpService) {
            return WxMpXmlOutMessage.TEXT()
                    .content("你好,世界!")
                    .fromUser(wxMessage.getToUser())
                    .toUser(wxMessage.getFromUser())
                    .build();
        }
    })
    .end();
// 在 Controller 中使用
@PostMapping("/wechat")
public String handlePost(@RequestBody String requestBody,
                         @RequestParam("signature") String signature,
                         @RequestParam("timestamp") String timestamp,
                         @RequestParam("nonce") String nonce,
                         @RequestParam("openid") String openid,
                         @RequestParam("encrypt_type") String encryptType) {
    // WxMpMessageRouter 会自动处理验证和消息解密
    return router.route(requestBody, signature, timestamp, nonce);
}

可以看到,使用 SDK 后,代码变得极其简洁和健壮。

3 学习资源

开发微信公众号 Java 应用,核心流程是:

  1. 配置:在公众号后台配置服务器地址和 Token。
  2. 验证:编写代码响应微信的 GET 请求,完成服务器身份验证。
  3. 交互:编写代码处理微信的 POST 请求(用户消息),并构造 XML 格式的回复。
  4. 调用:通过获取 access_token,调用微信 API 实现菜单、模板消息等功能。
  5. 部署:将应用部署到公网服务器,并配置 HTTPS 和反向代理。

从手动实现开始,有助于理解底层原理,但在实际项目中,强烈推荐使用 WxJava 这样的 SDK 来提高开发效率和代码质量,祝你开发顺利!

分享:
扫描分享到社交APP
上一篇
下一篇