SpringBoot整合调用微信模板方法实现微信公众号消息通知推送,Java实现微信公众号给关注用户推送自定义消息通知(手把手从0到1)

这篇具有很好参考价值的文章主要介绍了SpringBoot整合调用微信模板方法实现微信公众号消息通知推送,Java实现微信公众号给关注用户推送自定义消息通知(手把手从0到1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

概述

公众号给关注用户推送自定义消息

一、申请公众号模板消息

二、获取安装“web开发者工具”

三、微信网页授权说明

四、微信网页授权 - 流程时序图

五、HTTPClient 实现微信公众号消息推送与发布(四步走)

六、通过weixin-java-mp SDK实现微信公众号消息推送与发布(七步走)

七、抽取与封装


概述

本篇文章主要基于Java+Spring Boot+Spring Cloud的应用中接入微信公众号,调用微信的JavaSDK > weixin-java-mp进行应用消息推送,实现业务数据推送到指定的微信用户客户端。通过本篇博客,将快速上手,从0到1构建起消息推送与发布。

公众号给关注用户推送自定义消息

一、申请公众号模板消息

1、开通微信公众号平台的“模板消息”栏

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

提交申请:

添加功能插件>功能详情>申请开通模板接口> 填写业务服务目标所属的行业,申请理由,

如果是新申请的消息模板,需要注意规范,否则会被封号的可能!!!

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

等待审核通过就可以使用了!

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

“模板消息”开通审核通过后,在微信公众号平台>左边栏>广告与服务>就可以看到模板消息栏了,

接着,就可以添加用于业务系统推送公众号的模板消息内容了,

如下图: 

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

 添加完成后,就可以在,模板消息>我的模板,中进行查看了,如下图:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

关于推送的模板消息内容,用两种定义方式:
1、用公众号模板库已经存在的,也就是别人之前申请过的,
2、如果在模板消息库中检索不到符合当下业务系统需求的消息模板内容,则可以自定义,在模板库中选择“帮助我们完善模板库”
如下图:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

 添加自定义的微信公众号模板的内容的注意事项:
1、添加模版前,需要先仔细阅读《模版消息申请添加前必读指引》。请勿违反运营规则,否则可能被停用模版消息接口甚至封号的可能;
2、贡献新模版需要等待“7-15”天审核期,且内容可能被审核人员修改。每月只可申请新建3个新模版;
3、审核通过后,模版将放入模版库以供他人使用,会被官方共享出去,也就是这里的消息模板,没有私有这一说,之前博主的客户提需求,说必须要私有的,不能共享,因为这不是自己能控制的,遂进行了多轮沟通后最终才说服了客户;

二、获取安装“web开发者工具”

《web开发者工具稳定版下载》

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

微信web开发者工具,安装完成后,打开应用程序,选择“公众号网页项目”,
如下图;

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

为公众号绑定开发者:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

如果出现 “ 该微信用户未开启“公众号安全助手”的消息接收功能,请先开启后再绑定 ”

参考:

《该微信用户未开启“公众号安全助手”的消息接收功能,请先开启后再绑定》

邀请绑定,

设置完成后,再次邀请绑定即可完成绑定了,如下图:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

绑定成功后,再打开,微信公众号平台>设置与开发>开发者工具>选择“web开发者工具”>如下图(web开发者工具最多可绑定50人),
如下图:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

三、微信网页授权说明

1、微信开发网页授权五步走

第一步:用户同意授权,获取code
在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(已认证服务号,默认拥有 scope 参数中的snsapi_base和snsapi_userinfo 权限),引导关注者打开如下页面:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有 scope 参数对应的授权作用域权限。

注意:由于授权操作安全等级较高,所以在发起授权请求时,微信会对授权链接做正则强匹配校验,如果链接的参数顺序不对,授权页面将无法正常访问,跳转回调redirect_uri,应当使用 https 链接来确保授权 code 的安全性。

参考链接(请在微信客户端中打开此链接体验):

scope为snsapi_base:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect

scope为snsapi_userinfo:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

用户同意授权后

如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。

code说明:

code作为换取access_token的票据,每次用户授权带上的 code 将不一样,code只能使用一次,5分钟未被使用自动过期

请求参数说明:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

回调错误码说明:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

第二步:通过 code 换取网页授权access_token

首先请注意,这里通过 code 换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。

注意:由于公众号的 secret 和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起。

请求方法

获取 code 后,请求以下链接获取access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

请求参数说明:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节  

回调参数说明:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

回调错误码说明:

 springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

更多返回码说明请参看:

全局返回码说明

第三步:刷新access_token(可选项)

由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权。

请求方法

获取第二步的refresh_token后,请求以下链接获取access_token:

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

请求参数说明:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

回调参数说明:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

回调错误码说明:参看第二步回调错误码说明!

第四步:拉取用户信息(scope 为 snsapi_userinfo)

如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和 openid 拉取用户信息了。

请求方法

http:GET(请使用 https 协议):

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

关于scope授权作用域:

  /**
   * oauth2网页授权的scope.
   */
  public static class OAuth2Scope {
    /**
     * 不弹出授权页面,直接跳转,只能获取用户openid.
     */
    public static final String SNSAPI_BASE = "snsapi_base";

    /**
     * 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息.
     */
    public static final String SNSAPI_USERINFO = "snsapi_userinfo";

    /**
     * 手动授权,可获取成员的详细信息,包含手机、邮箱。只适用于企业微信或企业号.
     */
    public static final String SNSAPI_PRIVATEINFO = "snsapi_privateinfo";
  }

请求参数说明:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

回调参数说明:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

回调错误码说明:参看第二步回调错误码说明!

第五步:检验授权凭证(access_token)是否有效(可选项)

请求方法

http:GET(请使用 https 协议):

https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID

请求参数说明:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

回调参数说明:

两个参数(errcode、errmsg)

回调错误码说明:参看第二步回调错误码说明!

2、其它说明

一、关于网页授权回调域名的说明
1、在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头。


2、授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com 无法进行OAuth2.0鉴权。
3、如果公众号登录授权给了第三方开发者来进行管理,则不必做任何设置,由第三方代替公众号实现网页授权即可。

二、关于网页授权的两种 scope 的区别说明
1、以snsapi_base为 scope 发起的网页授权,是用来获取进入页面的用户的 openid 的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)。


2、以snsapi_userinfo为 scope 发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。


3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户 OpenID 来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。

三、关于网页授权access_token和普通access_token的区别
1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息。


2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。

四、微信网页授权 - 流程时序图

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

五、HTTPClient 实现微信公众号消息推送与发布(四步走)

第一步:获取微信公众号CODE

    /**
     * Description:[获取公众号CODE]
     *
     * @date 2019-05-19
     * @author huazai
     */
    @GetMapping("/getWeChatCode")
    @ApiOperation(value = "/getWeChatCode", notes = "获取公众号CODE")
    public void getWeChatCode(HttpServletResponse response) {
        try {
            // 构建公众号消息体
            String weChatGetCodeUrl = String.format(this.WE_CHAT_CODE_URL, this.WE_CHAT_APP_ID, this.WE_CHAT_CALL_BACK_DOMAIN_URL, WxConsts.OAuth2Scope.SNSAPI_BASE);
            log.info("we_chat_get_code_url:" + weChatGetCodeUrl);
            response.sendRedirect(weChatGetCodeUrl);

        } catch (Exception e) {
            log.info("异常信息:{}", e);
        }
    }

 请求回调获取的用户授权CODE,如下图:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

第二部:根据Code获取用户OpenId

    /**
     * Description:[根据Code获取用户OpenId]
     *
     * @return JSONResult
     * @date 2019-05-19
     * @author huazai
     */
    @GetMapping("/getWeChatOpenId")
    @ApiOperation(value = "/getWeChatOpenId", notes = "根据Code获取用户OpenId")
    public JSONResult getWeChatOpenId(@RequestParam String code, @RequestParam String state) {
        try {
            log.info("we_chat_code: " + code);
            String weChatDomain = String.format(this.WE_CHAT_AUTHORIZATION_URL, this.WE_CHAT_APP_ID, this.WE_CHAT_SECRET, code);

            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(weChatDomain, String.class);
            String openid = JSONObject.parseObject(responseEntity.getBody()).getString("openid");
            String access_token = JSONObject.parseObject(responseEntity.getBody()).getString("access_token");

            // 用户的OpenId,用户的微信授权Access_Token
            log.info("we_chat_open_id: " + openid);
            log.info("we_chat_access_token: " + access_token);

            return JSONResult.success(openid);
        } catch (Exception e) {
            log.info("异常信息:{}", e);
        }
        return null;
    }

 获取的openid如下图:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

第三步:根据Code获取用户Access_Token(可选)

    /**
     * Description:[根据Code获取用户Access_Token]
     *
     * @return JSONResult
     * @date 2019-05-19
     * @author huazai
     */
    @GetMapping("/getUserAccessToken")
    @ApiOperation(value = "/getUserAccessToken", notes = "根据Code获取用户Access_Token")
    public JSONResult getUserAccessToken(@RequestParam String code, @RequestParam String state) {
        try {
            String weChatDomain = String.format(this.WE_CHAT_AUTHORIZATION_URL, this.WE_CHAT_APP_ID, this.WE_CHAT_SECRET, code);
            log.info("we_chat_authorization_url:{}" + weChatDomain);

            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(weChatDomain, String.class);

            String accessToken = JSONObject.parseObject(responseEntity.getBody()).getString("access_token");
            log.info("we_chat_access_token: " + accessToken);

            return JSONResult.success(accessToken);
        } catch (Exception e) {
            log.info("异常信息:{}", e);
        }
        return null;
    }

第四步:获取微信公众号的Access_Token

    /**
     * Description:[获取微信公众号的Access_Token]
     *
     * @return JSONResult
     * @date 2019-05-19
     * @author huazai
     */
    @GetMapping("/getWeChatAccessToken")
    @ApiOperation(value = "/getWeChatAccessToken", notes = "微信公众号的Access_Token")
    public JSONResult getWeChatAccessToken() {
        try {
            // 微信公众号官方获取AccessToken
            RestTemplate restTemplate = new RestTemplate();
            String requestParams = String.format(this.WE_CHAT_ACCESS_TOKEN_URL, this.WE_CHAT_APP_ID, this.WE_CHAT_SECRET);
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(requestParams, String.class);

            String accessToken = JSONObject.parseObject(responseEntity.getBody()).getString("access_token");
            log.info("we_chat_access_token: " + accessToken);

            return JSONResult.success(accessToken);
        } catch (Exception e) {
            log.info("异常信息:{}", e);
        }
        return null;
    }

第五步:微信公众号指定用户消息推送与发布

    /**
     * Description:[公众号指定用户消息推送]
     *
     * @return JSONResult
     * @date 2019-05-19
     * @author huazai
     */
    @GetMapping("/sendWeChatRecharge")
    @ApiOperation(value = "/sendWeChatRecharge", notes = "公众号指定用户消息推送")
    public JSONResult sendWeChatRecharge() {

        // 1、构建公众号消息体
        WeChatRechargeTemplateParamsDTO weChatRechargeTemplateParamsDTO = WeChatRechargeTemplateParamsDTO.builder()
                .first("尊敬用户您好,你的缴费结果如下:")
                .keyword1("HuaZai")
                .keyword2("10010110010001")
                .keyword3(BigDecimal.valueOf(2000))
                .keyword4(BigDecimal.valueOf(10000182.92))
                .keyword5(DateUtil.getDateTime())
                .remark("缴费成功,祝您生活愉快!")
                .touser("**********")
                .customerNumber("549527")
                .build();

        // 2、组装消息数据
        Map<String, WeChatMsgDTO> weChatMsgMap = new HashMap<>();
        weChatMsgMap.put("first", new WeChatMsgDTO(weChatRechargeTemplateParamsDTO.getFirst()));
        weChatMsgMap.put("keyword1", new WeChatMsgDTO(weChatRechargeTemplateParamsDTO.getKeyword1()));
        weChatMsgMap.put("keyword2", new WeChatMsgDTO(weChatRechargeTemplateParamsDTO.getKeyword2()));
        weChatMsgMap.put("keyword3", new WeChatMsgDTO(weChatRechargeTemplateParamsDTO.getKeyword3().toString()));
        weChatMsgMap.put("keyword4", new WeChatMsgDTO(weChatRechargeTemplateParamsDTO.getKeyword4().toString()));
        weChatMsgMap.put("keyword5", new WeChatMsgDTO(weChatRechargeTemplateParamsDTO.getKeyword5()));
        weChatMsgMap.put("remark", new WeChatMsgDTO(weChatRechargeTemplateParamsDTO.getRemark()));
        String customerCallUrl = String.format(this.WE_CHAT_CUSTOMER_CALL_URL, weChatRechargeTemplateParamsDTO.getCustomerNumber());

        //3、构建模板消息体
        WeChatTemplateParamsDTO weChatTemplateParamsDTO = WeChatTemplateParamsDTO.builder()
                .touser(weChatRechargeTemplateParamsDTO.getTouser())
                .template_id(this.WE_CHAT_TEMPLATE_ID)
                .url(customerCallUrl)
                .topcolor(this.WE_CHAT_TOP_COLOR)
                .data(weChatMsgMap)
                .build();

        // 4、微信公众号消息推送与发布
        RestTemplate restTemplate = new RestTemplate();
        String resultUrl = String.format(this.WE_CHAT_REQUEST_URL, this.WE_CHAT_ACCESS_TOKEN);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(resultUrl, weChatTemplateParamsDTO, String.class);

        if (!OK.equals(responseEntity.getStatusCode())) {
            log.error("公众号消息推送失败!", responseEntity.getBody());
        }

        return JSONResult.success();
    }

消息推送,返回code为0,即表示消息已成功推送(否则失败,需要code码和上面的错误信息说明进行对比,针对性问题处理),如下图:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

再打开微信公众号,就可以看到推送的消息了,如下图:

 springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

常量说明:

    // 微信公众号的 app_id
    String WE_CHAT_APP_ID = "**********";
    // 微信公众号的 secret
    String WE_CHAT_SECRET = "**********";
    // 微信公众号的 access_token
    String WE_CHAT_ACCESS_TOKEN = "**********";
    // 微信公众号code获取地址
    String WE_CHAT_CODE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STATE#wechat_redirect";
    // 回调地址,获取open_id
    String WE_CHAT_CALL_BACK_DOMAIN_URL = "https://***.***.***.***/***/***/getWeChatOpenId";
    // 微信公众号的token获取地址
    String WE_CHAT_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
    // 微信公众号消息推送地址
    String WE_CHAT_REQUEST_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
    // 微信公众号推送消息模板id
    String WE_CHAT_TEMPLATE_ID = "**********";
    // 微信公众号的消息回调地址(这儿可根据业务需求自定义动作,可选)
    String WE_CHAT_CUSTOMER_CALL_URL = "https://***.***.***.***/***/***/accountInfo?keyword=%s";
    // 微信公众号的主题颜色
    String WE_CHAT_TOP_COLOR = "#A349A4";
    // 微信公众号微信用户授权地址
    String WE_CHAT_AUTHORIZATION_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";

六、通过weixin-java-mp SDK实现微信公众号消息推送与发布(七步走)

第一步:pom.xml新增依赖

        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-mp</artifactId>
            <version>4.3.0</version>
        </dependency>

第二步:配置WxMpService

配置me.chanjar.weixin.mp.api.WxMpService,可以通过@Component组件注入交由Spring进行管理,或者直接在启动类@SpringBootApplication中@Bean注入,

注入的内容如下:

    @Bean
    public WxMpService wxMpService() {
        WxMpMapConfigImpl wxMpMapConfig = new WxMpMapConfigImpl();
        wxMpMapConfig.setAppId(Constant.WE_CHAT_APP_ID);
        wxMpMapConfig.setSecret(Constant.WE_CHAT_SECRET);
        val wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpMapConfig);

        return wxMpService;
    }

 第三步:获取微信公众号CODE


    @Autowired
    private WxMpService wxMpService;


    /**
     * Description:[获取公众号CODE]
     *
     * @date 2019-05-19
     * @author huazai
     */
    @GetMapping("/getWeChatCode")
    @ApiOperation(value = "/getWeChatCode", notes = "获取公众号CODE")
    public RedirectView getWeChatCode() {
        try {
            // 构造网页授权url
            String authorizationUrl = wxMpService.getOAuth2Service().buildAuthorizationUrl(this.WE_CHAT_CALL_BACK_DOMAIN_URL, WxConsts.OAuth2Scope.SNSAPI_BASE, null);
            log.info("we_chat_get_code_url:" + authorizationUrl);

            return new RedirectView(authorizationUrl);
        } catch (Exception e) {
            log.info("异常信息:{}", e);
        }
        return null;
    }

第四步:根据Code获取用户OpenId

    /**
     * Description:[根据Code获取用户OpenId]
     *
     * @return JSONResult
     * @date 2019-05-19
     * @author huazai
     */
    @GetMapping("/getWeChatOpenId")
    @ApiOperation(value = "/getWeChatOpenId", notes = "根据Code获取用户OpenId")
    public JSONResult getWeChatOpenId(@RequestParam String code, @RequestParam String state) {
        try {
            log.info("we_chat_code: " + code);
            // 通过微信回调过来的code获得access token,其中也包含用户的openid等信息
            WxOAuth2AccessToken wxOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(code);

            String openid = wxOAuth2AccessToken.getOpenId();
            String access_token = wxOAuth2AccessToken.getAccessToken();
            // 用户的OpenId,用户的微信授权Access_Token
            log.info("we_chat_open_id: " + openid);
            log.info("we_chat_access_token: " + access_token);

            return JSONResult.success(openid);
        } catch (Exception e) {
            log.info("异常信息:{}", e);
        }
        return null;
    }

第五步:根据Code获取用户Access_Token(可选)

    /**
     * Description:[根据Code获取用户Access_Token]
     *
     * @return JSONResult
     * @date 2019-05-19
     * @author huazai
     */
    @GetMapping("/getUserAccessToken")
    @ApiOperation(value = "/getUserAccessToken", notes = "根据Code获取用户Access_Token")
    public JSONResult getUserAccessToken(@RequestParam String code, @RequestParam String state) {
        try {
            // 根据Code获取用户Access_Token
            WxOAuth2AccessToken wxOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(code);

            String accessToken = wxOAuth2AccessToken.getAccessToken();
            log.info("we_chat_user_access_token: " + accessToken);

            return JSONResult.success(accessToken);
        } catch (Exception e) {
            log.info("异常信息:{}", e);
        }
        return null;
    }

第六步:获取微信公众号的Access_Token
 

    /**
     * Description:[获取微信公众号的Access_Token]
     *
     * @return JSONResult
     * @date 2019-05-19
     * @author huazai
     */
    @GetMapping("/getWeChatAccessToken")
    @ApiOperation(value = "/getWeChatAccessToken", notes = "微信公众号的Access_Token")
    public JSONResult getWeChatAccessToken() {
        try {
            // 微信公众号官方获取AccessToken
            String accessToken = wxMpService.getAccessToken();
            log.info("we_chat_access_token: " + accessToken);

            return JSONResult.success(accessToken);
        } catch (Exception e) {
            log.info("异常信息:{}", e);
        }
        return null;
    }

第七步:微信公众号指定用户消息推送与发布

    /**
     * Description:[公众号指定用户消息推送]
     *
     * @return JSONResult
     * @date 2019-05-19
     * @author huazai
     */
    @GetMapping("/sendWeChatRecharge")
    @ApiOperation(value = "/sendWeChatRecharge", notes = "公众号指定用户消息推送")
    public JSONResult sendWeChatRecharge() {
        try {
            // 1、构建公众号消息体
            WeChatRechargeTemplateParamsDTO weChatRechargeTemplateParamsDTO = WeChatRechargeTemplateParamsDTO.builder()
                    .first("尊敬用户您好,你的缴费结果如下:")
                    .keyword1("HuaZai")
                    .keyword2("10010110010001")
                    .keyword3(BigDecimal.valueOf(2000))
                    .keyword4(BigDecimal.valueOf(10000182.92))
                    .keyword5(DateUtil.getDateTime())
                    .remark("缴费成功,祝您生活愉快!")
                    .touser("**********")
                    .customerNumber("549527")
                    .build();

            // 2、组装消息数据
            List<WxMpTemplateData> wxMpTemplateDataList = new ArrayList<>();
            wxMpTemplateDataList.add(new WxMpTemplateData("first", weChatRechargeTemplateParamsDTO.getFirst(), this.WE_CHAT_TOP_COLOR));
            wxMpTemplateDataList.add(new WxMpTemplateData("keyword1", weChatRechargeTemplateParamsDTO.getKeyword1(), this.WE_CHAT_TOP_COLOR));
            wxMpTemplateDataList.add(new WxMpTemplateData("keyword2", weChatRechargeTemplateParamsDTO.getKeyword2(), this.WE_CHAT_TOP_COLOR));
            wxMpTemplateDataList.add(new WxMpTemplateData("keyword3", weChatRechargeTemplateParamsDTO.getKeyword3().toString(), this.WE_CHAT_TOP_COLOR));
            wxMpTemplateDataList.add(new WxMpTemplateData("keyword4", weChatRechargeTemplateParamsDTO.getKeyword4().toString(), this.WE_CHAT_TOP_COLOR));
            wxMpTemplateDataList.add(new WxMpTemplateData("keyword5", weChatRechargeTemplateParamsDTO.getKeyword5(), this.WE_CHAT_TOP_COLOR));
            wxMpTemplateDataList.add(new WxMpTemplateData("remark", weChatRechargeTemplateParamsDTO.getRemark(), this.WE_CHAT_TOP_COLOR));
            String customerCallUrl = String.format(this.WE_CHAT_CUSTOMER_CALL_URL, weChatRechargeTemplateParamsDTO.getCustomerNumber());

            //3、构建模板消息体
            WxMpTemplateMessage wxMpTemplateMessage = WxMpTemplateMessage.builder()
                    .toUser(weChatRechargeTemplateParamsDTO.getTouser())
                    .templateId(this.WE_CHAT_TEMPLATE_ID)
                    .url(customerCallUrl)
                    .data(wxMpTemplateDataList)
                    .build();

            // 4、微信公众号消息推送与发布
            String msgId = wxMpService.getTemplateMsgService().sendTemplateMsg(wxMpTemplateMessage);
            log.error("公众号模板消息推送与发布结果:{}", msgId);
        } catch (Exception e) {
            log.info("异常信息:{}", e);
        }

        return JSONResult.success();
    }

七、抽取与封装

这儿的封装需要更具自身业务的不同,封装的深度也不同,需要自由抽取封装,但万变不离其宗,

1、简单工厂-普通模式

建立一个工厂类,对实现了同一接口的一些类进行实例的创建。

如下图:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

2、简单工厂-多方法模式

对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。

如下图:

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

3、简单工厂-多静态方法模式

将多工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

4、工厂方法模式

简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?

解决这个问题就用到工厂方法模式,创建一个工厂接口和创建多个工厂实现类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。

springboot微信消息推送,Java,Spring Boot,Spring,Java,Spring Boot,web网页授权,微信公众平台,MessageTemplate,1024程序员节

5、抽象工厂模式

工厂方法模式:

  1. 一个抽象产品类,可以派生出多个具体产品类;
  2. 一个抽象工厂类,可以派生出多个具体工厂类; 
  3. 每个具体工厂类只能创建一个具体产品类的实例;

抽象工厂模式:

  1. 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类;
  2. 一个抽象工厂类,可以派生出多个具体工厂类;
  3. 每个具体工厂类可以创建多个具体产品类的实例,也就是创建的是一个产品线下的多个产品;

区别:

  1. 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个;
  2. 工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个;
  3. 工厂方法创建 "一种" 产品,他的着重点在于"怎么创建",也就是说如果你开发,你的大量代码很可能围绕着这种产品的构造,初始化这些细节上面。也因为如此,类似的产品之间有很多可以复用的特征,所以会和模版方法相随;
  4. 抽象工厂需要创建一些列产品,着重点在于"创建哪些"产品上,也就是说,如果你开发,你的主要任务是划分不同差异的产品线,并且尽量保持每条产品线接口一致,从而可以从同一个抽象工厂继承;

对于Java应用程序来说,能见到的大部分抽象工厂模式都是这样的:里面是一堆工厂方法,每个工厂方法返回某种类型的对象。
例如:工厂可以生产鼠标和键盘。那么抽象工厂的实现类(它的某个具体子类)的对象都可以生产鼠标和键盘,但可能工厂 A 生产的是先科的键盘和鼠标,工厂 B 是Microsoft的。这样 A 和 B 就是工厂,对应于抽象工厂;每个工厂生产的鼠标和键盘就是产品,对应于工厂方法;用了工厂方法模式,你替换生成键盘的工厂方法,就可以把键盘从先科如丝滑般的切换到Microsoft。但是用了抽象工厂模式,要想切换工厂 C 的雷蛇,就可以同时替换鼠标和键盘一套。如果产品有几十个,当然用抽象工厂模式一次替换全部最方便快捷(工厂会替换相应的工厂方法)

所以抽象工厂就像工厂,而工厂方法则像是工厂的一种产品生产线!!!

微信公众号开发注意两点:
1、公众号开发获取调用auoth2授权接口获取,Token_assecc授权时,需要授权IP,
参考:
《errcode“:40164,“errmsg“:“invalid ip ...微信公众号开发调用失败的解决办法》
2、在发布时,由于是基于Web页面开发的,需要授权域名的绑定验证,
参考:
《微信公众号开发redirect_uri 参数错误 的解决办法,Oauth2授权重定向域名参数错误解决办法》

3、SpringBoot整合调用微信模板方法实现微信公众号消息通知推送

《 HTTPClient 实现微信公众号消息推送与发布(四步走) 》

4、SpringBoot整合调用微信模板方法实现微信公众号消息通知推送

《 通过weixin-java-mp SDK实现微信公众号消息推送与发布(七步走) 》

参考:

【公众号模板消息接口文档】

【微信网页开发-Web开发者工具下载】

【微信开发包】更多内容查看WIKI,MP_OAuth2网页授权

【模板消息接口文档】

【MP_OAuth2网页授权】


 好了,关于 SpringBoot整合调用微信模板方法实现微信公众号消息通知推送,Java实现微信公众号给关注用户推送自定义消息通知(从0到1)  就写到这儿了,如果还有什么疑问或遇到什么问题欢迎扫码提问,也可以给我留言哦,我会一一详细的解答的。 
歇后语:“ 共同学习,共同进步 ”,也希望大家多多关注CSND的IT社区。文章来源地址https://www.toymoban.com/news/detail-688833.html


作       者: 华    仔
联系作者: who.seek.me@java98k.vip
来        源: CSDN (Chinese Software Developer Network)
原        文: https://blog.csdn.net/Hello_World_QWP/article/details/125871196
版权声明: 本文为博主原创文章,请在转载时务必注明博文出处!

到了这里,关于SpringBoot整合调用微信模板方法实现微信公众号消息通知推送,Java实现微信公众号给关注用户推送自定义消息通知(手把手从0到1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【微信公众号】14、SpringBoot整合WxJava加解密的异常处理办法

    如果在加解密的过程中出现 java.security.InvalidKeyException: Illegal key size,则需要根据不同的 JDK 版本下载一个东西: 1、JRE/JDK 6 下载地址: 2、JRE/JDK 7 下载地址:

    2024年02月16日
    浏览(44)
  • 微信公众号模板消息源码实现,打破服务号群发推送次数限制

    公众号服务号每个月只能群发推送四次文章,我们可以使用模板消息为公众号粉丝推送信息 下面是使用golang实现的模板消息发送类库封装,轻松实现模板消息发送 wechat.go 我们的使用方式 推送的效果如图所示,点击模板就能跳转到我们自定义的url上 我在自己客服系统中也是

    2024年02月15日
    浏览(43)
  • 微信公众号二维码扫码登录(SpringBoot Java实现)

    用户扫描公众号的二维码,实现登录当前平台。 若未关注公众号,则关注后触发登录;若已关注,则直接登录。  登录时通过union_id判断用户是否在系统注册,若未注册则跳转到注册页面或提示未注册。 注意,此功能使用的接口,需要 公众号类型为 服务号 才支持! 开发阶

    2024年02月12日
    浏览(43)
  • springboot整合feign实现RPC调用,并通过Hystrix实现服务降级

    feign/openfeign和dubbo是常用的微服务RPC框架,由于feigin内部已经集成ribbon,自带了负载均衡的功能,当有多个同名的服务注册到注册中心时,会根据ribbon默认的负载均衡算法将请求分配到不同的服务。这篇文章就简单介绍一下怎么使用feign来调用远程的服务。 首先,需要有一个

    2024年02月16日
    浏览(39)
  • 微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用

    🏷️ 个人主页 :鼠鼠我捏,要死了捏的主页  🏷️ 系列专栏 :Golang全栈-专栏 🏷️ 个人学习笔记,若有缺误,欢迎评论区指正   前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站AI学习网站。 目录 前言 快速上手

    2024年02月19日
    浏览(33)
  • 微信公众号推送模板消息给用户

    前置条件: 1.公众号为服务号,而非订阅号 2.认证(300元) 3.进入公众号申请模板推送功能 4.添加模板(注意:推送的消息只能使用微信提供的模板,不可自定义,但也是比较全的) 4.2 获取accessToken时,需要将开发环境的电脑ip添加到微信后台的ip白名单(线上环境亦是如此

    2024年02月12日
    浏览(54)
  • uniapp - 微信小程序平台模板消息订阅功能,唤起订阅模板消息弹框、微信公众号向用户发送 “服务通知“ 实现全过程示例代码,支持一次性订阅与永久性订阅(注释详细,一键复制开箱即用)

    本博客实现了uniapp微信小程序端,详细实现公众号订阅通知模板消息完整示例源码,一次性订阅与永久订阅均可,注释详细新手一看就懂! 效果如图所示,uniapp编译的微信小程序内点击按钮后,唤起模板消息订阅申请弹框,后续微信内会收到通知。

    2024年02月13日
    浏览(45)
  • 微信小程序向公众号推送消息模板

    由于微信小程序长期订阅的消息模板全部失效以后,对于小程序的消息推送可以改成往公众号推。 这里将介绍如何使用小程序向公众号推送消息,并且消息可以跳转到小程序 1、微信公众平台注册 服务号 (订阅号是不可以推送的)与小程序,两者都需要认证并且 认证主体是

    2024年02月06日
    浏览(49)
  • java springboot 整合webSocket接入调用chatGPT3.5接口实现自由返回

    java springboot 中使用webSocket接入openAI接口调用chatGPT3.5接口实现自由返回 @Component @Anonymous @ServerEndpoint(“/websocket/{id}”) // 访问路径: ws://localhost:8080/websocket public class WebSocketServer { // try { // sendMessage(“WebSocket连接成功”); // } catch (Exception e) { // // } } /** * 发送消息 * @param message 要

    2024年02月14日
    浏览(50)
  • 互联网大厂技术-HTTP请求-Springboot整合Feign更优雅地实现Http服务调用

    目录 一、SpringBoot快速整合Feign 1.添加Pom依赖 2.启动类添加注解 3.引用Feign服务 二、为请求添加Header的3种方式 1.添加固定header 2.通过接口签名添加header 3.动态添加header 三、为请求添加超时配置 1.默认超时时间 3.超时异常 4.全局超时配置 5.为单个服务设置超时配置 四、为请求配

    2024年02月04日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包