1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > JAVA对接微信公众号(服务号 订阅号)实现模板消息推送功能

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

时间:2022-01-11 20:30:27

相关推荐

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

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

大概逻辑分为四个步骤:

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

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

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

@Overridepublic String getAccessToken() {RestTemplate restTemplate = new RestTemplate();String accessTokenUrl = getAccessTokenUrl + "?grant_type=" + grantType + "&appid=" + appId + "&secret=" + secret;ResponseEntity<JSONObject> 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;}@Overridepublic List<MsgTemplateVO> 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<MsgTemplateVO> templateVOList = new ArrayList<>();ResponseEntity<JSONObject> 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_credentialwechat.auth.token=tokenwechat.auth.appid=服务号的appIdwechat.auth.secret=服务号的secret#获取AccessToken url GETwechat.url.accesstoken=https://api./cgi-bin/token#模板消息推送 POSTwechat.url.template.send=https://api./cgi-bin/message/template/send#获取所有的消息模板 GETwechat.url.get.all.template=https://api./cgi-bin/template/get_all_private_template

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

//send urlString sendUrl = templateSendUrl + "?access_token=" + accessToken;JSONObject params = new JSONObject();params.put("touser", "openid");params.put("template_id", msgTemplateVO.getTemplateId());//模板参数params.put("data", contentJson);//headerHttpHeaders header = new HttpHeaders();header.setContentType(MediaType.APPLICATION_JSON);//HttpEntityHttpEntity<JSONObject> httpEntity = new HttpEntity<>(params, header);RestTemplate restTemplate = new RestTemplate();//JSONObject数据结果JSONObject result = restTemplate.postForObject(sendUrl, httpEntity, JSONObject.class);//返回结果List<MsgMiddleResult> 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。具体的使用方法可以参考这篇文章/p/571fdbc98d25

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。