springboot+微信公众号发送模板消息+小程序发送订阅消息

测试号管理:https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

在开发之前需要做的事情:

1.申请一个公众号测试账号,一分钟就可以申请下来   

2.然后需要一个微信验证token的地址,这个大家可以网上找一下 比较简单。

验证token的代码贴一下

package com.cjkj.message.controller;

import com.cjkj.message.utils.SignUtil;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * @program: cjkj
 * @description:
 * @author: Mr.Wang
 * @create: 2020-03-25 17:11
 **/
@Controller
@RequestMapping("/wechat")
public class WechatController {

        private static Logger logger = Logger.getLogger(WechatController.class);

        @RequestMapping(value = "security", method = RequestMethod.GET)
        public void doGet(
                HttpServletRequest request,
                HttpServletResponse response,
                @RequestParam(value = "signature", required = true) String signature,
                @RequestParam(value = "timestamp", required = true) String timestamp,
                @RequestParam(value = "nonce", required = true) String nonce,
                @RequestParam(value = "echostr", required = true) String echostr) {
            try {
                if (SignUtil.checkSignature(signature, timestamp, nonce)) {
                    PrintWriter out = response.getWriter();
                    out.print(echostr);
                    out.close();
                } else {
                    logger.info("这里存在非法请求!");
                }
            } catch (Exception e) {
                logger.error(e, e);
            }
        }

        @RequestMapping(value = "security", method = RequestMethod.POST)
        // post方法用于接收微信服务端消息
        public void DoPost() {
            System.out.println("这是post方法!");
        }
    }

3.token验证成功后,用自己的微信扫描关注公众号。

4.创建一个自定义的模板。

我的模板事这个:

{ {first.DATA}} 用户名:{ {keyword1.DATA}} 订单号:{ {keyword2.DATA}} 订单金额:{ {keyword3.DATA}} 商品信息:{ {keyword4.DATA}} { {remark.DATA}}

复制粘贴进去就可以了。

 

5.上边的话我们就可以看到appID,appsecret,关注用户的微信号,也就是openid。然后还有自己船舰的模板id(模板ID(用于接口调用))

接下来我们用代码就可以实现了。

我的代码中包含了一些业务代码,大家看的时候跳过。同时我们的appID,appsecret保存在数据库,当调用的时候 ,通过参数appkey去查询到这两个参数。

wechat:
  #获取token的地址
  getTokenUrl: https://api.weixin.qq.com/cgi-bin/token
  #发送公众号消息的地址
  sendMsgUrl: https://api.weixin.qq.com/cgi-bin/message/template/send
  #发送小程序的消息地址
  sendMiniPUrl: https://api.weixin.qq.com/cgi-bin/message/subscribe/send
@RestController
@RequestMapping("/wechat")
public class WechatMessageController {
    private static Logger logger = Logger.getLogger(WechatMessageController.class);
    @Autowired
    private WechatService wechatService;

    /**
     * 公众号发送模板消息
     * @return
     */
    @ApiOperation(value="公众号发送模板消息", notes="根据参数发送模板消息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "WechatTokenEntity", value = "公众号实体", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "data", value = "模板信息参数json结构的字符串", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "miniprogram", value = "小程序参数json结构字符串", required = true, paramType = "query", dataType = "String")
    })
    @RequestMapping(value="/sendMessage" ,method = {RequestMethod.POST})
    public com.cjwl.ResultData sendMessage(HttpServletRequest request, WechatOfficialEntity wechatOfficialEntity, @RequestParam String data, @RequestParam String miniProgram) {
        return wechatService.sendMsg(request, wechatOfficialEntity, data, miniProgram);
}

    /**
     * 小程序发送模板消息
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "MiniProgramEntity", value = "小程序实体", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "data", value = "发送信息参数json结构的字符串", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "miniprogram", value = "小程序参数json结构字符串", required = true, paramType = "query", dataType = "String")
    })
    @RequestMapping(value="/sendMiniProgramMessage", method = {RequestMethod.POST})
    public com.cjwl.ResultData miniPSendMessage(HttpServletRequest re
<think>嗯,用户想用Java Spring Boot开发微信服务号的订阅通知功能,我得先理清楚整个流程。首先,用户可能对微信公众平台的开发流程不太熟悉,可能需要先介绍一些基本步骤。 首先,注册服务号并认证是必须的,因为只有认证的服务号才能申请模板消息或者订阅通知的权限。然后,需要配置服务器,这涉及到微信的验证流程,比如验证消息的确来自微信服务器。这里可能需要用到Spring Boot的Controller来处理GET请求,验证签名什么的。 接下来,申请订阅消息模板。微信现在可能已经从模板消息转向了订阅通知,所以用户需要注意接口的变化。用户需要知道如何获取模板ID,以及模板里的各个参数怎么配置。 然后是用户订阅的事件处理。当用户关注服务号或者点击订阅按钮时,微信会发送一个事件到配置的服务器,这时候需要用Controller来接收这个事件,并触发发送订阅通知的请求。可能需要用HTTP客户端比如RestTemplate或者Feign来调用微信的接口。 发送订阅通知的时候,要构造正确的JSON数据,包括用户的OpenID、模板ID、跳转的页面、数据内容等。还要注意access_token的获取和缓存,避免频繁调用导致接口限制。这里可能需要用Redis或者缓存机制来保存token,定时刷新。 用户可能会有疑问,比如如何保证安全性,比如验证消息的真实性,处理敏感数据。还有可能遇到哪些常见问题,比如签名错误、token失效、模板参数不对等,需要给出调试建议,比如用微信的测试号先进行开发,查看日志等。 另外,用户可能想知道如何让用户触发订阅,比如通过菜单按钮或者回复关键字,这时候需要设计相应的交互流程。同时,订阅通知的发送时机也很重要,不能频繁打扰用户,否则可能被投诉。 还有,返回结果的处理,比如发送成功或失败后的逻辑,是否需要重试或者记录日志。异常处理也是关键,比如网络问题导致调用微信接口失败,应该如何处理。 总之,整个流程需要分步骤讲解,从配置公众号、服务器设置、处理订阅事件、获取token、发送消息到异常处理,每个环节都要详细说明,并且给出代码示例,这样用户才能更好地理解和实现。</think>使用Java Spring Boot开发微信服务号订阅通知功能,主要分为以下步骤: --- ### **1. 准备工作** - **注册微信服务号**:完成企业认证(订阅通知功能需认证的服务号)。 - **配置服务器信息**: - 登录微信公众平台,进入**开发 > 基本配置**,启用服务器配置(填写Spring Boot应用的公网URL和Token)。 - **申请订阅消息模板**: - 在微信公众平台**功能 > 订阅消息**中创建模板,获取`template_id`。 --- ### **2. Spring Boot项目搭建** #### 依赖配置(`pom.xml`): ```xml <!-- 核心依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- HTTP客户端(如发送微信API请求) --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <!-- JSON处理 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.83</version> </dependency> ``` --- ### **3. 实现核心逻辑** #### (1) **验证微信服务器(GET请求)** 微信会通过GET请求验证服务器有效性,需在Controller中处理: ```java @RestController public class WechatController { @GetMapping("/wechat") public String validate(@RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce, @RequestParam("echostr") String echostr) { // 1. 将token、timestamp、nonce按字典序排序并拼接 // 2. SHA1加密后与signature比对 // 3. 验证成功返回echostr return checkSignature(signature, timestamp, nonce) ? echostr : "error"; } } ``` #### (2) **获取Access Token** 调用微信API需要凭证`access_token`,需定时刷新(建议缓存): ```java @Component public class WechatTokenService { private String accessToken; @Scheduled(fixedRate = 7200 * 1000 - 600) // 每2小时刷新一次 public void refreshToken() { String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APPID}&secret={APPSECRET}"; ResponseEntity<String> response = restTemplate.getForEntity(url, String.class); JSONObject json = JSON.parseObject(response.getBody()); this.accessToken = json.getString("access_token"); } } ``` #### (3) **处理用户订阅事件** 当用户触发订阅操作(如点击订阅按钮),微信会发送事件到服务器: ```java @PostMapping("/wechat") public String handleMessage(@RequestBody String body) { // 解析XML消息 Map<String, String> msgMap = parseXmlMessage(body); if ("event".equals(msgMap.get("MsgType")) && "subscribe".equals(msgMap.get("Event"))) { // 用户订阅事件,触发发送订阅通知 sendSubscribeMessage(msgMap.get("FromUserName")); } return "success"; } ``` #### (4) **发送订阅通知** 调用微信订阅消息接口(需替换模板参数): ```java public void sendSubscribeMessage(String openId) { String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken; JSONObject data = new JSONObject(); // 填充模板内容(根据申请的模板字段) data.put("thing1", JSON.parseObject("{'value':'您有新的订单'}")); data.put("time2", JSON.parseObject("{'value':'2024-01-01 12:00'}")); JSONObject requestBody = new JSONObject(); requestBody.put("touser", openId); requestBody.put("template_id", "YOUR_TEMPLATE_ID"); requestBody.put("page", "pages/index"); // 跳转的小程序页面(非必填) requestBody.put("data", data); // 发送HTTP POST请求 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> entity = new HttpEntity<>(requestBody.toJSONString(), headers); restTemplate.postForObject(url, entity, String.class); } ``` --- ### **4. 关键注意事项** 1. **安全性**:验证消息签名,防止伪造请求。 2. **模板匹配**:确保模板ID和参数与申请的一致。 3. **频率限制**:微信API有调用频率限制(如每天5000次)。 4. **用户授权**:部分场景需用户主动同意接收通知(如一次性订阅)。 --- ### **5. 调试工具** - **微信公众平台测试号**:通过测试号快速开发(无需正式服务号)。 - **日志记录**:记录微信API请求与响应,便于排查问题。 - **Postman**:模拟微信服务器发送事件消息。 --- 通过以上步骤,即可实现订阅通知的发送。具体代码需根据实际业务调整模板参数和用户触发逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值