阅读 20

springboot微信公众号关键词回复图片 springboot微信公众号跳转网页

第一步:vue端

1)App.vue类

import sdk from ./router/share; // 引入sdk. mounted() { /* eslint-disable */ const url = location.href.split(#)[0]; console.log(url) const dataForWeixin = { title: 分享标题, // 分享标题 desc: 分享内容, // 分享内容 linkurl: "http://nhh.ngrok.ibanzhuan.cn", // 分享链接 img: http://show.1m2.net/sj/static/img/sharre.jpg, // 分享内容显示的图片(图片必须是正方形的链接) }; const ua = window.navigator.userAgent.toLowerCase(); if (ua.match(/MicroMessenger/i) === micromessenger) { sdk.getJSSDK(url,dataForWeixin); //传入sdk.js需要的参数 } else { console.log(不是微信浏览器) sdk.getJSSDK(url,dataForWeixin); } },

其中,title、desc、linkurl、img这四个为分享的设置,linkurl应动态获取当前前端页面地址

const dataForWeixin = { title: 分享标题, // 分享标题 desc: 分享内容, // 分享内容 linkurl: "http://192.168.0.124", // 分享链接 img: http://show.1m2.net/sj/static/img/sharre.jpg, // 分享内容显示的图片(图片必须是正方形的链接) };

2)share.js

import wx from weixin-js-sdk import axios from axios; // 要用到微信API function getJSSDK(url, dataForWeixin) { // 调用后台接口换取参数 axios.get(http://nhc.ngrok.ibanzhuan.cn/app/wechat/initJSSDKConfig, { params: { url, }, }).then((res) => { console.log(res) wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: res.data.map.appid, // 必填,公众号的唯一标识 timestamp: res.data.map.timestamp, // 必填,生成签名的时间戳 nonceStr: res.data.map.nonceStr, // 必填,生成签名的随机串 signature: res.data.map.signature, // 必填,签名 jsApiList: [onMenuShareAppMessage, onMenuShareTimeline, updateAppMessageShareData, updateTimelineShareData,onMenuShareQQ,onMenuShareWeibo] // 必填,需要使用的JS接口列表 }); wx.ready(function () { wx.onMenuShareAppMessage({ title: dataForWeixin.title, desc: dataForWeixin.desc, link: dataForWeixin.linkurl, imgUrl: dataForWeixin.img, success: function () { // 用户确认分享后执行的回调函数 alert(分享成功); }, cancel: function () { // 用户取消分享后执行的回调函数 } }); wx.error(function(res){ // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 alert("errorMSG:"+res); }); }); }); } export default { // 获取JSSDK getJSSDK, }

其中,接口

http://nhc.ngrok.ibanzhuan.cn/app/wechat/initJSSDKConfig 为后端地址获取公众号基本配置的接口,在第二步讲述。

第二步:springboot接口

Controller类

package com.qh.app.controller; import com.qh.app.annotation.CompanyNum; import com.qh.app.service.WechatService; import com.qh.app.utils.WechatUtil; import com.qh.common.response.BaseResponse; import com.qh.common.utils.AgrLogUtils; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.Map; /** * @Author :nhchun * @Date: 2020/4/16 9:01 * @Desc: **/ @CrossOrigin @RestController @RequestMapping("/app/wechat") public class AppWechatController { public final static Logger logger = AgrLogUtils.getLogger(AppWechatController.class); @Autowired WechatService wechatService; /** * 获取公众号接入的初始配置 * @param url * @param companyNum * @return */ @GetMapping("/initJSSDKConfig") public BaseResponse initJSSDKConfig(@RequestParam(name="url")String url,@CompanyNum String companyNum) { Map map = wechatService.initJSSDKConfig(url, companyNum); return BaseResponse.ok().put("map",map); } }

Service类

这里我把公众号的一些参数appid、appsecret、jssdk_accesstoken_url、jssdk_getticket_url配置到数据库中了,当然也可以放置在属性文件application.yml中。

package com.qh.app.service.impl; import com.qh.app.repository.AppConfigRepository; import com.qh.app.service.WechatService; import com.qh.app.utils.WechatUtil; import com.qh.common.entity.ConfigEntity; import com.qh.common.exception.BizException; import com.qh.common.exception.ResultEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * @Author :nhchun * @Date: 2020/4/16 15:08 * @Desc: **/ @Service public class WechatServiceImpl implements WechatService { @Autowired AppConfigRepository configRepository; @Override public Map initJSSDKConfig(String url,String companyNum) { Map<String,String> map = new HashMap<String,String>(); try { //1 获取数据库配置 ConfigEntity configEntity = getConfigEntity(companyNum); //2 获取AccessToken String accessToken = WechatUtil.getJSSDKAccessToken(configEntity.getJssdkAccesstokenUrl(), configEntity.getAppID(),configEntity.getAppsecret()); //3 获取JssdkGetticket String jsapiTicket = WechatUtil.getJssdkGetticket(configEntity.getJssdkGetticketUrl(), accessToken); //4 签名 String timestamp = Long.toString(System.currentTimeMillis() / 1000); String nonceStr = UUID.randomUUID().toString(); String signature = WechatUtil.buildJSSDKSignature(jsapiTicket, timestamp, nonceStr, url); //5 返回 map.put("url", url); map.put("jsapi_ticket", jsapiTicket); map.put("nonceStr", nonceStr); map.put("timestamp", timestamp); map.put("signature", signature); map.put("appid", configEntity.getAppID()); }catch(Exception e){ throw new BizException(ResultEnum.FAIL); } return map; } private ConfigEntity getConfigEntity(String companyNum) { ConfigEntity configEntity = configRepository.queryByCompanyNum(companyNum); if (configEntity == null) { throw new BizException(ResultEnum.COMPANYNUM_NO_CONFIG); } return configEntity; } }

WechatUtil工具类

package com.qh.app.utils; ​ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.qh.common.utils.RedisUtil; import com.qh.common.utils.StringUtils; import me.chanjar.weixin.common.util.crypto.SHA1; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.security.MessageDigest; imort java.util.Map; ​ /** * @Author :nhchun * @Date: 2020/4/16 9:11 * @Desc: **/ @Component public class WechatUtil { public static final String TOKEN ="sckt"; public static boolean validParams(String signature,String timestamp,String nonce){ try { return SHA1.gen(new String[]{TOKEN, timestamp, nonce}).equals(signature); } catch (Exception var5) { return false; } } /** * 获取access_token * @return */ public static String getJSSDKAccessToken(String JssdkAccesstokenUrl,String AppId,String AppSecret) { String token = null; //1 去緩存取 token= RedisUtil.getString("ACESSTOKEN"+AppId); if(!StringUtils.isNullOrEmpty(token)){ return token; } //2 重新获取 String url = JssdkAccesstokenUrl.replaceAll("APPID", AppId).replaceAll("APPSECRET", AppSecret); String json = postRequestForWeiXinService(url); Map map = jsonToMap(json); if (map != null) { token = (String) map.get("access_token"); } RedisUtil.setString("ACESSTOKEN"+AppId,token,7200); return token; } public static String getJssdkGetticket(String JssdkGetticketUrl,String accessToken) { String jsapi_ticket = null; jsapi_ticket= RedisUtil.getString("jsapi_ticket"+accessToken); if(!StringUtils.isNullOrEmpty(jsapi_ticket)){ return jsapi_ticket; } String url = JssdkGetticketUrl.replaceAll("ACCESS_TOKEN", accessToken); String json = postRequestForWeiXinService(url); Map map = jsonToMap(json); if (map != null) { jsapi_ticket = (String) map.get("ticket"); } RedisUtil.setString("jsapi_ticket"+accessToken,jsapi_ticket,7200); return jsapi_ticket; } /** *@Author: nhc *@CreateTime: 21:41 2020/2/14 *@param:ticket 根据accessToken生成的JssdkGetticket *@param:timestamp 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 *@param:nonceStr 随机字符串 *@param:url 当前网页的URL *@Description: 构建分享链接的签名 */ public static String buildJSSDKSignature(String ticket,String timestamp,String nonceStr ,String url) throws Exception { String orderedString = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url; return sha1(orderedString); } /** * sha1 加密JSSDK微信配置参数获取签名。 * * @return */ public static String sha1(String orderedString) throws Exception { String ciphertext = null; MessageDigest md = MessageDigest.getInstance("SHA-1"); byte[] digest = md.digest(orderedString.getBytes()); ciphertext = byteToStr(digest); return ciphertext.toLowerCase(); } /** * 将字节数组转换为十六进制字符串 * * @param byteArray * @return */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * 将字节转换为十六进制字符串 * @param mByte * @return */ private static String byteToHexStr(byte mByte) { 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[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } /** *@Author: nhc *@CreateTime: 21:49 2020/2/14 *@param: map *@Description: mapToJson */ public static String mapToJson(Map map){ Gson gson = new Gson(); String json = gson.toJson(map); return json; } /** *@Author:nhc *@CreateTime: 21:37 2020/2/14 *@param: json *@Description: jsonToMap */ private static Map jsonToMap(String json) { Gson gons = new Gson(); Map map = gons.fromJson(json, new TypeToken<Map>(){}.getType()); return map; } /** *@Author: nhchun *@CreateTime: 21:36 2020/2/14 *@param: * @param null *@Description: 调取微信接口 */ private static String postRequestForWeiXinService(String getAccessTokenUrl) { RestTemplate restTemplate = new RestTemplate(); ResponseEntity<String> postForEntity = restTemplate.postForEntity(getAccessTokenUrl, null, String.class); String json = postForEntity.getBody(); return json; } }

这个工具类中access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值,我把它放在redis缓存中了。

分享成功如下

springboot微信公众号关键词回复图片 springboot微信公众号跳转网页(图1)

当然,调试过程中,可能还会遇到其它的问题,后续会补充。。。

说明:关注微信公众号【村中一少】,回复“电子书”按照提示信息获取对应书籍目录序号,如回复【1】,即可获得电子书【研磨设计模式.陈臣.王斌.扫描版.pdf】下载地址,所有电子均为免费。

这些电子书仅仅用于学习,如果喜欢请购买正版图书!请支持原版作者!

文章分类
百科问答
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐