JAVA对接微信公众号(服务号、订阅号)实现模板消息推送功能

您所在的位置:网站首页 怎么微信发公众号消息 JAVA对接微信公众号(服务号、订阅号)实现模板消息推送功能

JAVA对接微信公众号(服务号、订阅号)实现模板消息推送功能

2024-07-08 16:31| 来源: 网络整理| 查看: 265

最近做了个需求要求对接微信公众号,使用模板进行消息推送,今天抽时间总结一下相关的逻辑。

大概逻辑分为四个步骤:

获取微信调用接口凭证access_token。获取微信模板列表。使用模板进行消息推送。公众号配置服务器URL。

我这里的实现没有使用微信公众号weixin-java-mp依赖,完全是根据微信官方文档的提示写的代码。

一、二、获取access_token和模板列表

@Override public String getAccessToken() { RestTemplate restTemplate = new RestTemplate(); String accessTokenUrl = getAccessTokenUrl + "?grant_type=" + grantType + "&appid=" + appId + "&secret=" + secret; ResponseEntity responseEntity = restTemplate.getForEntity(accessTokenUrl, JSONObject.class); if (responseEntity.getStatusCodeValue() == 200) { JSONObject result = responseEntity.getBody(); if (result != null) { int errCode = result.getIntValue("errcode"); if (errCode == 0) { String accessToken = result.getString("access_token"); redisTemplate.opsForValue().set(WeChatConstant.WECHAT_ACCESS_TOKEN_REDIS_KEY, accessToken, 7200, TimeUnit.SECONDS); return accessToken; } else { String errMsg = result.getString("errmsg"); logger.info("获取微信access_token返回失败,错误码:{},错误信息:{}", errCode, errMsg); } } else { logger.info("获取微信返回结果json为空"); } } else { logger.info("调用微信接口请求失败"); } return null; } @Override public List getAllTemplates() { RestTemplate restTemplate = new RestTemplate(); String accessToken = redisTemplate.opsForValue().get(WeChatConstant.WECHAT_ACCESS_TOKEN_REDIS_KEY); if (StringUtils.isBlank(accessToken)) { accessToken = this.getAccessToken(); } String url = getAllTemplateUrl + "?access_token=" + accessToken; List templateVOList = new ArrayList(); ResponseEntity responseEntity = restTemplate.getForEntity(url, JSONObject.class); if (responseEntity.getStatusCodeValue() == 200) { JSONObject result = responseEntity.getBody(); if (result != null) { JSONArray array = result.getJSONArray("template_list"); if (!array.isEmpty()) { for (int i = 0; i < array.size(); i++) { JSONObject template = array.getJSONObject(i); MsgTemplateVO msgTemplateVO = new MsgTemplateVO(); msgTemplateVO.setTemplateId(template.getString("template_id")); msgTemplateVO.setTitle(template.getString("title")); msgTemplateVO.setPrimaryIndustry(template.getString("primary_industry")); msgTemplateVO.setPrimaryIndustry(template.getString("deputy_industry")); msgTemplateVO.setContent("content"); msgTemplateVO.setContent("example"); templateVOList.add(msgTemplateVO); } } } else { logger.info("获取微信模板返回结果json为空"); } } else { logger.info("调用微信模板接口请求失败"); } return templateVOList; }

说明:MsgTeplateVO是我自己定义的消息模板类。

properties配置请求接口的常量

wechat.auth.granttype=client_credential wechat.auth.token=token wechat.auth.appid=服务号的appId wechat.auth.secret=服务号的secret #获取AccessToken url GET wechat.url.accesstoken=https://api.weixin.qq.com/cgi-bin/token #模板消息推送 POST wechat.url.template.send=https://api.weixin.qq.com/cgi-bin/message/template/send #获取所有的消息模板 GET wechat.url.get.all.template=https://api.weixin.qq.com/cgi-bin/template/get_all_private_template

 

三、使用模板进行消息推送主要代码。参数设置,发送请求,获取结果

//send url String sendUrl = templateSendUrl + "?access_token=" + accessToken; JSONObject params = new JSONObject(); params.put("touser", "openid"); params.put("template_id", msgTemplateVO.getTemplateId()); //模板参数 params.put("data", contentJson); //header HttpHeaders header = new HttpHeaders(); header.setContentType(MediaType.APPLICATION_JSON); //HttpEntity HttpEntity httpEntity = new HttpEntity(params, header); RestTemplate restTemplate = new RestTemplate(); //JSONObject数据结果 JSONObject result = restTemplate.postForObject(sendUrl, httpEntity, JSONObject.class); //返回结果 List results = msgRecordVO.getResults(); if (result != null) { Integer errCode = result.getInteger("errcode"); if (errCode == 0) { //成功 } else { //失败 String errMsg = result.getString("errmsg"); } } 自己使用测试号,定义了模板,写了测试类进行测试如下:

四、公众号配置服务器URL

@GetMapping("/checkSignature") public String checkSignature(HttpServletRequest request) { String signature = request.getParameter("signature"); String timestamp = request.getParameter("timestamp"); String nonce = request.getParameter("nonce"); String echostr = request.getParameter("echostr"); logger.info("接收来自微信服务器的认证信息。signature={},timestamp={},nonce={},echostr={}", signature, timestamp, nonce, echostr); if(StringUtils.isAnyBlank(signature,timestamp,nonce,echostr)){ logger.info("请求参数非法"); return null; } //加密后的mySignature与微信公众平台的signature一致 boolean check = SignUtil.checkSignature(token, signature, timestamp, nonce); if (check) { return echostr; } return null; } /** * 校验签名 * * @param token 服务器配置里写的TOKEN * @param signature 签名 * @param timestamp 时间戳 * @param nonce 随机数 * @return true 成功,false 失败 */ public static boolean checkSignature(String token, String signature, String timestamp, String nonce) { String checkText = null; if (null != signature) { //对Token,timestamp nonce 按字典排序 String[] paramArr = new String[]{token, timestamp, nonce}; Arrays.sort(paramArr); //将排序后的结果拼成一个字符串 String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]); try { MessageDigest md = MessageDigest.getInstance("SHA-1"); //对接后的字符串进行sha1加密 byte[] digest = md.digest(content.getBytes()); checkText = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } //将加密后的字符串与signature进行对比 return checkText != null && checkText.equals(signature.toUpperCase()); } /** * 将字节数组转化为16进制字符串 * * @param byteArrays 字符数组 * @return 字符串 */ private static String byteToStr(byte[] byteArrays) { StringBuilder str = new StringBuilder(); for (byte byteArray : byteArrays) { str.append(byteToHexStr(byteArray)); } return str.toString(); } /** * 将字节转化为十六进制字符串 * * @param myByte 字节 * @return 字符串 */ private static String byteToHexStr(byte myByte) { char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; char[] tempArr = new char[2]; tempArr[0] = digit[(myByte >>> 4) & 0X0F]; tempArr[1] = digit[myByte & 0x0F]; return new String(tempArr); }

我这里是测试接口用了ngrok。具体的使用方法可以参考这篇文章https://www.jianshu.com/p/571fdbc98d25

注:在验证token的时候,我是写在配置文件里了,如果使用文章开始的jar包。可以通过appId直接获取到。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3