当前位置:   article > 正文

微信接口_wxmpxmlmessage inmessage = wxmpxmlmessage.fromencr

wxmpxmlmessage inmessage = wxmpxmlmessage.fromencryptedxml(requestbody, wxse

微信官方文档 | 微信开放文档

1.在 pom.xml 中添加微信开发 SDK 依赖:

  1. <dependency>
  2. <groupId>com.github.binarywang</groupId>
  3. <artifactId>weixin-java-mp</artifactId>
  4. <version>3.5.0</version>
  5. </dependency>

2.创建一个处理微信消息的 Controller:

  1. @RestController
  2. @RequestMapping("/wx/portal")
  3. public class WxPortalController {
  4. private final WxMpService wxService;
  5. public WxPortalController(WxMpService wxService) {
  6. this.wxService = wxService;
  7. }
  8. @GetMapping(produces = "text/plain;charset=utf-8")
  9. public String authGet(@RequestParam(name = "signature", required = false) String signature,
  10. @RequestParam(name = "timestamp", required = false) String timestamp,
  11. @RequestParam(name = "nonce", required = false) String nonce,
  12. @RequestParam(name = "echostr", required = false) String echostr) {
  13. if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
  14. throw new IllegalArgumentException("请求参数非法,请核实!");
  15. }
  16. if (this.wxService.checkSignature(timestamp, nonce, signature)) {
  17. return echostr;
  18. }
  19. return "非法请求";
  20. }
  21. @PostMapping(produces = "application/xml; charset=UTF-8")
  22. public String post(@RequestBody String requestBody, @RequestParam("signature") String signature,
  23. @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce,
  24. @RequestParam(name = "encrypt_type", required = false) String encType,
  25. @RequestParam(name = "msg_signature", required = false) String msgSignature) {
  26. if (!this.wxService.checkSignature(timestamp, nonce, signature)) {
  27. throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
  28. }
  29. String out = null;
  30. if (encType == null) {
  31. // 明文传输的消息
  32. WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
  33. WxMpXmlOutMessage outMessage = this.route(inMessage);
  34. if (outMessage == null) {
  35. return "";
  36. }
  37. out = outMessage.toXml();
  38. } else if ("aes".equals(encType)) {
  39. // aes加密的消息
  40. WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, this.wxService.getWxMpConfigStorage(), timestamp, nonce, msgSignature);
  41. WxMpXmlOutMessage outMessage = this.route(inMessage);
  42. if (outMessage == null) {
  43. return "";
  44. }
  45. out = outMessage.toEncryptedXml(this.wxService.getWxMpConfigStorage());
  46. }
  47. return out;
  48. }
  49. private WxMpXmlOutMessage route(WxMpXmlMessage message) {
  50. try {
  51. return this.wxService.route(message);
  52. } catch (Exception e) {
  53. log.error(e.getMessage(), e);
  54. }
  55. return null;
  56. }
  57. }

在上述代码中,我们创建了一个 WxPortalController 控制器类,在其中添加了两个方法分别用于处理 GET 请求和 POST 请求。这些方法接受微信发送过来的参数,并使用 WxMpService 对象进行验证和处理。其中,WxMpService 是对微信公众号相关接口进行封装的类,我们可以通过依赖注入的方式获取它的实例。

3.在 application.yml 中配置微信相关的信息:

  1. wx:
  2. mp:
  3. app-id: your-app-id
  4. secret: your-app-secret
  5. token: your-token
  6. aes-key: your-aes-key

在上述配置中,我们使用了 wx.mp 作为微信公众号相关配置的前缀,并在下面分别设置了 AppID、AppSecret、Token 和 AES Key 的值。这些值可以在微信公众平台中获取到。

5.启动 Spring Boot 应用程序,并将接口地址填写到微信公众平台中的开发者中心中。

例如,假设你的应用程序运行在 8080 端口,接口地址为 /wx/portal,那么你就可以将 http://your-domain.com/wx/portal 填写到微信公众平台中的开发者中心的 URL 配置中。

微信网页授权流程主要包括以下几个步骤:

1.构造授权链接:生成一个跳转到微信授权页面的链接,用户点击后将跳转到微信授权页面。

2.用户授权:用户在微信授权页面上确认授权登录,并同意授权给你的应用获取用户信息。

3.获取授权 code:微信授权页面重定向回你指定的 redirect_uri 并携带授权 code。

4.通过 code 获取 access_token:使用授权 code 调用微信接口,获取 access_token 和 openid。

5.获取用户信息:使用 access_token 和 openid 调用微信接口,获取用户的基本信息。

下面是在 Spring 中实现微信网页授权流程的示例代码:

1.构造授权链接:

  1. String appId = "your_app_id";
  2. String redirectUri = "your_redirect_uri";
  3. String scope = "snsapi_userinfo";
  4. String state = "your_state_parameter"; // 可选,可以用于防止 CSRF 攻击
  5. String authorizeUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&response_type=code&scope=" + scope + "&state=" + state + "#wechat_redirect";
  6. // 将 authorizeUrl 返回给前端,让用户点击该链接进行授权

2.获取授权 code:

  1. // 在 redirectUri 对应的 Controller 方法中获取 code
  2. @RequestMapping("/redirectUri")
  3. public String handleRedirectUri(@RequestParam("code") String code, @RequestParam("state") String state) {
  4. // 将 code 和 state 参数保存,用于后续获取 access_token
  5. // 然后重定向到获取用户信息的方法
  6. return "redirect:/getUserInfo?code=" + code + "&state=" + state;
  7. }

3.通过 code 获取 access_token:

  1. RestTemplate restTemplate = new RestTemplate();
  2. String appId = "your_app_id";
  3. String appSecret = "your_app_secret";
  4. String code = "the_code_from_previous_step";
  5. String accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code";
  6. ResponseEntity<String> response = restTemplate.getForEntity(accessTokenUrl, String.class);
  7. String responseData = response.getBody();
  8. // 解析 JSON 格式的响应数据,获取 access_token 和 openid
  9. JSONObject jsonObject = new JSONObject(responseData);
  10. String accessToken = jsonObject.getString("access_token");
  11. String openid = jsonObject.getString("openid");

用户同意授权后,微信会重定向回你指定的 redirect_uri,并在URL中带上参数 code,该 code 是临时票据,用于换取 access_token 和用户的 OpenID。

也就是说,你需要使用这个 code 去请求微信的 API 来获取 access_token。具体来说,你可以通过调用如下 API 来完成 access_token 的获取:

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

其中,APPID 是你的公众号 AppID,SECRET 是你的公众号 AppSecret,CODE 是前面得到的 code。该 API 将返回一个 JSON 格式的响应,包含了 access_token 等相关信息。

需要注意的是,获取 access_token 的接口与微信网页授权接口不同,如果你需要获取用户的基本信息,还需要调用其他的 API(如 https://api.weixin.qq.com/sns/userinfo)来获取用户的信息。

4.获取用户信息:

  1. String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
  2. ResponseEntity<String> response = restTemplate.getForEntity(userInfoUrl, String.class);
  3. String responseData = response.getBody();
  4. // 解析 JSON 格式的响应数据,获取用户信息
  5. JSONObject jsonObject = new JSONObject(responseData);
  6. String nickname = jsonObject.getString("nickname");
  7. String headImgUrl = jsonObject.getString("headimgurl");
  8. // 其他的用户信息字段...
  9. // 在这里可以根据需要处理用户信息

认证接口配置

  1. @Api("认证接口配置")
  2. @Slf4j
  3. @AllArgsConstructor
  4. @RestController
  5. @RequestMapping("/wx/portal/{appid}")
  6. public class WxPortalController {
  7. private final WxMpService wxService;
  8. private final WxMpMessageRouter messageRouter;
  9. @ApiOperation(value = "接收微信服务器的认证消息")
  10. @GetMapping(produces = "text/plain;charset=utf-8")
  11. public String authGet(@PathVariable String appid,
  12. @RequestParam(name = "signature", required = false) String signature,
  13. @RequestParam(name = "timestamp", required = false) String timestamp,
  14. @RequestParam(name = "nonce", required = false) String nonce,
  15. @RequestParam(name = "echostr", required = false) String echostr) {
  16. log.info("\n接收到来自微信服务器的认证消息:[{}, {}, {}, {}]", signature,
  17. timestamp, nonce, echostr);
  18. if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
  19. throw new IllegalArgumentException("请求参数非法,请核实!");
  20. }
  21. if (!this.wxService.switchover(appid)) {
  22. throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
  23. }
  24. if (wxService.checkSignature(timestamp, nonce, signature)) {
  25. return echostr;
  26. }
  27. return "非法请求";
  28. }
  29. @ApiOperation(value = "接收微信请求")
  30. @PostMapping(produces = "application/xml; charset=UTF-8")
  31. public String post(@PathVariable String appid,
  32. @RequestBody String requestBody,
  33. @RequestParam("signature") String signature,
  34. @RequestParam("timestamp") String timestamp,
  35. @RequestParam("nonce") String nonce,
  36. @RequestParam("openid") String openid,
  37. @RequestParam(name = "encrypt_type", required = false) String encType,
  38. @RequestParam(name = "msg_signature", required = false) String msgSignature) {
  39. log.info("\n接收微信请求:[openid=[{}], [signature=[{}], encType=[{}], msgSignature=[{}],"
  40. + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
  41. openid, signature, encType, msgSignature, timestamp, nonce, requestBody);
  42. if (!this.wxService.switchover(appid)) {
  43. throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
  44. }
  45. if (!wxService.checkSignature(timestamp, nonce, signature)) {
  46. throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
  47. }
  48. String out = null;
  49. if (encType == null) {
  50. // 明文传输的消息
  51. WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
  52. WxMpXmlOutMessage outMessage = this.route(inMessage);
  53. if (outMessage == null) {
  54. return "";
  55. }
  56. out = outMessage.toXml();
  57. } else if ("aes".equalsIgnoreCase(encType)) {
  58. // aes加密的消息
  59. WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxService.getWxMpConfigStorage(),
  60. timestamp, nonce, msgSignature);
  61. log.debug("\n消息解密后内容为:\n{} ", inMessage.toString());
  62. WxMpXmlOutMessage outMessage = this.route(inMessage);
  63. if (outMessage == null) {
  64. return "";
  65. }
  66. out = outMessage.toEncryptedXml(wxService.getWxMpConfigStorage());
  67. }
  68. log.debug("\n组装回复信息:{}", out);
  69. return out;
  70. }
  71. private WxMpXmlOutMessage route(WxMpXmlMessage message) {
  72. try {
  73. return this.messageRouter.route(message);
  74. } catch (Exception e) {
  75. log.error("路由消息时出现异常!", e);
  76. }
  77. return null;
  78. }
  79. }

新增配置文件application.yml

  1. wx:
  2. mp:
  3. useRedis: true
  4. redisConfig:
  5. host: 127.0.0.1
  6. port: 6379
  7. #password:
  8. timeout: 2000
  9. configs:
  10. - appId: #测试号appid
  11. secret: #测试号appsecret
  12. token: #测试号接口配置信息填写的token
  13. aesKey: 111
  14. # 开发环境配置
  15. server:
  16. # 服务器的HTTP端口,默认为8080
  17. port: 80
  18. logging:
  19. level:
  20. org.springframework.web: info
  21. com.wckj.binarywang.demo.wx.pay: debug
  22. com.wckj.binarywang.wxpay: debug

读取配置信息

  1. @Data
  2. @ConfigurationProperties(prefix = "wx.mp")
  3. public class WxMpProperties {
  4. /**
  5. * 是否使用redis存储access token
  6. */
  7. private boolean useRedis;
  8. /**
  9. * redis 配置
  10. */
  11. private RedisConfig redisConfig;
  12. @Data
  13. public static class RedisConfig {
  14. /**
  15. * redis服务器 主机地址
  16. */
  17. private String host;
  18. /**
  19. * redis服务器 端口号
  20. */
  21. private Integer port;
  22. /**
  23. * redis服务器 密码
  24. */
  25. private String password;
  26. /**
  27. * redis 服务连接超时时间
  28. */
  29. private Integer timeout;
  30. }
  31. /**
  32. * 多个公众号配置信息
  33. */
  34. private List<MpConfig> configs;
  35. @Data
  36. public static class MpConfig {
  37. /**
  38. * 设置微信公众号的appid
  39. */
  40. private String appId;
  41. /**
  42. * 设置微信公众号的app secret
  43. */
  44. private String secret;
  45. /**
  46. * 设置微信公众号的token
  47. */
  48. private String token;
  49. /**
  50. * 设置微信公众号的EncodingAESKey
  51. */
  52. private String aesKey;
  53. }
  54. @Override
  55. public String toString() {
  56. return JsonUtils.toJson(this);
  57. }
  58. }
  1. @AllArgsConstructor
  2. @Configuration
  3. @EnableConfigurationProperties(WxMpProperties.class)
  4. public class WxMpConfiguration {
  5. private final LogHandler logHandler;
  6. private final NullHandler nullHandler;
  7. private final KfSessionHandler kfSessionHandler;
  8. private final StoreCheckNotifyHandler storeCheckNotifyHandler;
  9. private final LocationHandler locationHandler;
  10. private final MenuHandler menuHandler;
  11. private final MsgHandler msgHandler;
  12. private final UnsubscribeHandler unsubscribeHandler;
  13. private final SubscribeHandler subscribeHandler;
  14. private final ScanHandler scanHandler;
  15. private final WxMpProperties properties;
  16. @Bean
  17. public WxMpService wxMpService() {
  18. // 代码里 getConfigs()处报错的同学,请注意仔细阅读项目说明,你的IDE需要引入lombok插件!!!!
  19. final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
  20. if (configs == null) {
  21. throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
  22. }
  23. WxMpService service = new WxMpServiceImpl();
  24. service.setMultiConfigStorages(configs
  25. .stream().map(a -> {
  26. WxMpDefaultConfigImpl configStorage;
  27. if (this.properties.isUseRedis()) {
  28. final WxMpProperties.RedisConfig redisConfig = this.properties.getRedisConfig();
  29. JedisPoolConfig poolConfig = new JedisPoolConfig();
  30. JedisPool jedisPool = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(),
  31. redisConfig.getTimeout(), redisConfig.getPassword());
  32. configStorage = new WxMpRedisConfigImpl(new JedisWxRedisOps(jedisPool), a.getAppId());
  33. System.out.println("JedisPool连接成功:"+redisConfig.getHost()+"\t"+redisConfig.getPort());
  34. } else {
  35. configStorage = new WxMpDefaultConfigImpl();
  36. }
  37. configStorage.setAppId(a.getAppId());
  38. configStorage.setSecret(a.getSecret());
  39. configStorage.setToken(a.getToken());
  40. configStorage.setAesKey(a.getAesKey());
  41. return configStorage;
  42. }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
  43. return service;
  44. }
  45. @Bean
  46. public WxMpMessageRouter messageRouter(WxMpService wxMpService) {
  47. final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
  48. // 记录所有事件的日志 (异步执行)
  49. newRouter.rule().handler(this.logHandler).next();
  50. // 接收客服会话管理事件
  51. newRouter.rule().async(false).msgType(EVENT).event(KF_CREATE_SESSION)
  52. .handler(this.kfSessionHandler).end();
  53. newRouter.rule().async(false).msgType(EVENT).event(KF_CLOSE_SESSION)
  54. .handler(this.kfSessionHandler).end();
  55. newRouter.rule().async(false).msgType(EVENT).event(KF_SWITCH_SESSION)
  56. .handler(this.kfSessionHandler).end();
  57. // 门店审核事件newRouter.rule().async(false).msgType(EVENT).event(POI_CHECK_NOTIFY).handler(this.storeCheckNotifyHandler).end();
  58. // 自定义菜单事件
  59. newRouter.rule().async(false).msgType(EVENT).event(EventType.CLICK).handler(this.menuHandler).end();
  60. // 点击菜单连接事件
  61. newRouter.rule().async(false).msgType(EVENT).event(EventType.VIEW).handler(this.nullHandler).end();
  62. // 关注事件
  63. newRouter.rule().async(false).msgType(EVENT).event(SUBSCRIBE).handler(this.subscribeHandler).end();
  64. // 取消关注事件newRouter.rule().async(false).msgType(EVENT).event(UNSUBSCRIBE).handler(this.unsubscribeHandler).end();
  65. // 上报地理位置事件
  66. newRouter.rule().async(false).msgType(EVENT).event(EventType.LOCATION).handler(this.locationHandler).end();
  67. // 接收地理位置消息newRouter.rule().async(false).msgType(XmlMsgType.LOCATION).handler(this.locationHandler).end();
  68. // 扫码事件newRouter.rule().async(false).msgType(EVENT).event(EventType.SCAN).handler(this.scanHandler).end();
  69. // 默认
  70. newRouter.rule().async(false).handler(this.msgHandler).end();
  71. return newRouter;
  72. }
  73. }

Application启动类

  1. @SpringBootApplication
  2. public class WxMpDemoApplication {
  3. public static void main(String[] args) {
  4. SpringApplication.run(WxMpDemoApplication.class, args);
  5. }
  6. }

启动项目,前往微信公众平台,将接口配置信息填写完整,appid就是测试号的appid,token可以任意填写但要与后台配置文件的保持一致。

发送消息给指定用户

这里实现服务器配置中设置的服务器URL请求接口,验证配置的令牌是否生效。

  1. @Slf4j
  2. @RestController
  3. public class WeChatController {
  4. private static final String TOKEN = "cc2fb962b7bb37833008d65e905614c8";
  5. private static final String APPID="wxf1e42af3ecad28c7";
  6. private static final String APPSECRET="cc2fb962b7bb37833008d65e905614c8";
  7. /**
  8. * 微信验证token
  9. *
  10. * @param signature
  11. * @param timestamp
  12. * @param nonce
  13. * @param echostr
  14. * @return
  15. */
  16. @GetMapping("/checkTokenNotice.do")
  17. public String checkToken(@RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp,
  18. @RequestParam("nonce") String nonce, @RequestParam("echostr") String echostr) {
  19. //排序
  20. String[] arr = {TOKEN, timestamp, nonce};
  21. Arrays.sort(arr);
  22. StringBuilder content = new StringBuilder();
  23. for (int i = 0; i < arr.length; i++) {
  24. content.append(arr[i]);
  25. }
  26. //sha1Hex 加密
  27. MessageDigest md = null;
  28. String temp = null;
  29. try {
  30. md = MessageDigest.getInstance("SHA-1");
  31. byte[] digest = md.digest(content.toString().getBytes());
  32. temp = byteToStr(digest);
  33. log.info("加密后的token:" + temp);
  34. } catch (NoSuchAlgorithmException e) {
  35. e.printStackTrace();
  36. }
  37. if ((temp.toLowerCase()).equals(signature)) {
  38. return echostr;
  39. }
  40. return null;
  41. }
  42. private static String byteToStr(byte[] byteArray){
  43. String strDigest = "";
  44. for (int i = 0; i < byteArray.length; i++) {
  45. strDigest += byteToHexStr(byteArray[i]);
  46. }
  47. return strDigest;
  48. }
  49. private static String byteToHexStr(byte mByte){
  50. char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A','B', 'C', 'D', 'E', 'F' };
  51. char[] tempArr = new char[2];
  52. tempArr[0] = Digit[(mByte >>> 4)& 0X0F];
  53. tempArr[1] = Digit[mByte & 0X0F];
  54. String s = new String(tempArr);
  55. return s;
  56. }
  57. }

这个接口是微信请求用户授权地址,具体如何触发授权,这个需由具体业务需求而定,这里不做赘述。因为我只需要用到微信用户的openID,所以本文中用到的是静默授权登录(scope=snsapi_base),即不需要微信用户显式授权,不足之处是获取的用户信息较少。所以这里需要具体业务做选择。

  1. @Override
  2. public String weChatAuth(SendSmsParam req) {
  3. //这个url的域名必须要进行在公众号中进行注册验证,这个地址是成功后的回调地址
  4. String callBackUrl = "";
  5. if ("uat".equals(mark)) {
  6. callBackUrl = backUrl + "/uat/api/installment/vip/login/getOpenid.pub?mobile=" + req.getMobile();
  7. } else {
  8. callBackUrl = backUrl + "/api/installment/vip/login/getOpenid.pub?mobile=" + req.getMobile();
  9. }
  10. // 静默授权登录(scope=snsapi_base),一种为非静默授权登录(scope=snsapi_userinfo)
  11. String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appID + "&redirect_uri=" + URLEncoder.encode(callBackUrl) + "&response_type=code"
  12. + "&scope=snsapi_base" + "&state=STATE#wechat_redirect";
  13. log.info("forward重定向地址{" + url + "}");
  14. return "redirect:" + url;
  15. }

这个接口是微信授权成功后的回调地址,用户授权后,获得授权码,再请求获取openId接口,得到openId,进行进一步的业务操作。

  1. @Override
  2. public void getOpenidNotice(HttpServletRequest request, HttpServletResponse response) {
  3. String code = request.getParameter("code");
  4. String mobile = request.getParameter("mobile");
  5. log.info("手机号码[{}]", mobile);
  6. try {
  7. request.setCharacterEncoding("UTF-8");
  8. //通过获取access_token获得openid和access_token
  9. String backResult = HttpUtil.get("https://api.weixin.qq.com/sns/oauth2/access_token?appid="
  10. + appID + "&secret=" + appSecret + "&code=" + code +
  11. "&grant_type=authorization_code");
  12. //根据用户Access_token和openid获取用户信息
  13. log.info("用户openId[{}]", backResult);
  14. }
  15. }

调用消息发送接口发送微信消息到指定用户。

  1. public Boolean sendWeChatMsg(List<MessageRecordDTO> messageRecordList) {
  2. Boolean sendFlag = true;
  3. //从redis中获取accessToken
  4. String accessToken = redisCacheService.getMap(MAP_NAME, MAP_KEY);
  5. if (StrUtil.isBlank(accessToken)) {
  6. accessToken = this.getAndSetAccessToken();
  7. }
  8. for (MessageRecordDTO messageRecordDTO : messageRecordList) {
  9. UserPO userPO = userManager.getById(messageRecordDTO.getUserId());
  10. if (ObjectUtil.isNull(userPO)) {
  11. continue;
  12. }
  13. // 根据配置的消息模板构建消息体发送。
  14. Map<String, MsgElement> dataMap = getMsgElementMap(messageRecordDTO);
  15. String extend2 = userPO.getExtend2();
  16. if (StrUtil.isNotBlank(extend2)) {
  17. WeChatMsgDTO weChatMsgDTO = new WeChatMsgDTO(extend2, msgTemplateId, dataMap);
  18. String json = JSON.toJSONString(weChatMsgDTO);
  19. String result = "";
  20. try {
  21. result = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken, json);
  22. } catch (Exception e) {
  23. log.error("发送微信消息失败", e);
  24. sendFlag = false;
  25. messageRecordDTO.setSendState("2");
  26. if (messageRecordDTO.getFirstFlag() == null) {
  27. DelayTaskScheduler.putWithDefaultStrategy(
  28. new SyncRetryWechatNoticeTask(), new SyncRetryWechatNoticeMessage(messageRecordDTO, weChatMsgService), null);
  29. }
  30. }
  31. log.info("消息记录[{}],微信消息发送结果[{}]", messageRecordDTO.getId(), result);
  32. // 发送成功后,可继续进行业务操作
  33. }
  34. }
  35. return sendFlag;
  36. }
  37. private Map<String, MsgElement> getMsgElementMap(MessageRecordDTO messageRecordDTO) {
  38. Map<String, MsgElement> elementMap = new HashMap<>();
  39. elementMap.put("first", new MsgElement("亲爱的用户,您有一条新的消息", "#000000"));
  40. elementMap.put("keyword1", new MsgElement(ENMessageTypeEnum.getLabelByValue(messageRecordDTO.getMsgType()), "#000000"));
  41. elementMap.put("keyword2", new MsgElement(this.getSendMsg(messageRecordDTO), "#000000"));
  42. elementMap.put("keyword3", new MsgElement(DateTimeUtil.getDateTimeFormat(messageRecordDTO.getCreateTime()), "#000000"));
  43. return elementMap;
  44. }

这里涉及到每次发送时,需要accessToken,微信设置的过期时间是2小时,我的处理方式是将accessToken存放到redis中,淘汰时间设置同微信官方过期时间,交由redis来维护accessToken。实现代码如下所示:

  1. private String getAndSetAccessToken() {
  2. String accessToken = "";
  3. String backResult = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appID + "&secret=" + appSecret);
  4. if (StrUtil.isNotBlank(backResult)) {
  5. WeChatTokenDTO weChatTokenDTO = JSON.parseObject(backResult, WeChatTokenDTO.class);
  6. accessToken = weChatTokenDTO.getAccess_token();
  7. redisCacheService.setMap(MAP_NAME, MAP_KEY, accessToken, weChatTokenDTO.getExpires_in());
  8. }
  9. return accessToken;
  10. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/274110
推荐阅读
相关标签
  

闽ICP备14008679号