经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
SpringBoot接入微信JSSDK,看这篇妥妥的
来源:cnblogs  作者:JavaDog程序狗  时间:2023/3/24 9:09:29  对本文有异议

先给猴急的客官上干货代码

GitHub

接入微信JSSDK GitHub地址

Gitee

接入微信JSSDK GitHub地址

前言

事情的起因是因为疫情严重,领导要求做一个专题页,能够尽可能帮助所需要的人。
于是乎本狗与同事挑灯奋战,加班加点赶工出来。
部署上线完成,用微信内置浏览器分享后,理想状态应该是这样的,如下图??


但是,结果却不是理想的这样,默默地留下了没有技术的泪水,如下图??

竟然没有关键字和展示图片,在本菜狗的不懈努力下,终于承认技术不行,去请教了大佬,得出如下结论。

  • 1.微信内置浏览器分享若需要自定义展示描述及右侧封面图,必须接入微信JSSDK,并且一定需要有配合本站的微信公众号(appId和appSecret)才可自定义分享,切记小程序(appId和appSecret)的不可以
  • 2.非微信分享,如QQ浏览器,UC浏览器等各大厂商,会根据自身定义获取HTML页面中的TDK(title,description,keyword),举例UC浏览器分享??

    在这里插入图片描述
    所以,对接微信JSSDK,势在必行!

Tip

史上最详细的接入微信JSSDK菜鸟教程,本文全面的记录了接入微信JSSDK的步骤,具体的代码及遇到的坑,并且展示发布最终效果,并将代码发布GitHub。随篇幅较长,但史上最全。大佬勿喷,新手入门,亲测可用!!!

本文试用人群

  • 需要接入微信JSSDK却看不懂文档的同学
  • 看懂文档但是实操不知如何下手的同学
  • 下了手但是出错不知道如何调试修改的同学
  • 成功接入过但是想重温具体流程的同学

本文目标

  • 实战进行H5网站微信自定义分享
  • 实战进行H5网站调取相册选取图片

放松心态,慢慢来看


正文

官方文档

任何平台接入,官方文档是标杆,虽有些关键点一笔带过,我们也要通读有个印象,点击微信官方文档打开文档,如下??
在这里插入图片描述

总览
  • 1.x是接入关键步骤,需仔细品读,与接入有关
  • 2.x - 12.x 具体接口接入,需要对接时具体参考
  • 13.x 需要注意下,api_ticket 微信临时票据,与接入有关
  • 16-22 均是附录,可查阅错误列表对应含义,及接口菜单列表等描述

实操步骤

使用IDEA工具,新建SpringBoot项目,项目名为springboot-wexin,目录结构如下
在这里插入图片描述
AjaxJson.java - 自定义接口返回前台数据格式的封装类

  1. /**
  2. * Copyright &copy; 2005-2020 <a href="http://www.jhmis.com/">jhmis</a> All rights reserved.
  3. */
  4. package net.javadog.springbootwexin.common;
  5. import com.fasterxml.jackson.annotation.JsonIgnore;
  6. import java.util.LinkedHashMap;
  7. import java.util.List;
  8. /**
  9. * $.ajax后需要接受的JSON
  10. *
  11. */
  12. public class AjaxJson {
  13. private boolean success = true;// 是否成功
  14. private String errorCode = "-1";//错误代码
  15. private String msg = "操作成功";// 提示信息
  16. private Long count; //返回表格记录数量
  17. private List<?> data; //返回表格数据
  18. private LinkedHashMap<String, Object> body = new LinkedHashMap<String, Object>();//封装json的map
  19. public static AjaxJson ok(){
  20. AjaxJson j = new AjaxJson();
  21. return j;
  22. }
  23. public static AjaxJson ok(String msg){
  24. AjaxJson j = new AjaxJson();
  25. j.setMsg(msg);
  26. return j;
  27. }
  28. public static AjaxJson ok(String msg, Object object){
  29. AjaxJson j = new AjaxJson();
  30. j.setMsg(msg);
  31. j.setResult(object);
  32. return j;
  33. }
  34. public static AjaxJson ok(Object object){
  35. AjaxJson j = new AjaxJson();
  36. j.setResult(object);
  37. return j;
  38. }
  39. public static AjaxJson fail(String errorMsg){
  40. AjaxJson j = new AjaxJson();
  41. j.setSuccess(false);
  42. j.setErrorCode("999");//默认错误码
  43. j.setMsg(errorMsg);
  44. return j;
  45. }
  46. public static AjaxJson fail(String errorCode,String errorMsg){
  47. AjaxJson j = new AjaxJson();
  48. j.setSuccess(false);
  49. j.setErrorCode(errorCode);
  50. j.setMsg(errorMsg);
  51. return j;
  52. }
  53. //返回不分页的layui表数据
  54. public static AjaxJson layuiTable(List<?> list){
  55. AjaxJson j = new AjaxJson();
  56. j.setSuccess(true);
  57. j.setCount(Long.valueOf(list.size()));
  58. j.setData(list);
  59. return j;
  60. }
  61. public LinkedHashMap<String, Object> getBody() {
  62. return body;
  63. }
  64. public void setBody(LinkedHashMap<String, Object> body) {
  65. this.body = body;
  66. }
  67. public void put(String key, Object value){//向json中添加属性,在js中访问,请调用data.map.key
  68. body.put(key, value);
  69. }
  70. public void remove(String key){
  71. body.remove(key);
  72. }
  73. /**
  74. * 直接设置result内容
  75. * @param result
  76. */
  77. public void setResult(Object result){
  78. body.put("result", result);
  79. }
  80. @JsonIgnore//返回对象时忽略此属性
  81. public Object getResult(){
  82. return body.get("result");
  83. }
  84. public String getMsg() {
  85. return msg;
  86. }
  87. public void setMsg(String msg) {//向json中添加属性,在js中访问,请调用data.msg
  88. this.msg = msg;
  89. }
  90. public boolean isSuccess() {
  91. return success;
  92. }
  93. public void setSuccess(boolean success) {
  94. this.success = success;
  95. }
  96. public void setErrorCode(String errorCode) {
  97. this.errorCode = errorCode;
  98. }
  99. public String getErrorCode() {
  100. return errorCode;
  101. }
  102. public Long getCount() {
  103. return count;
  104. }
  105. public void setCount(Long count) {
  106. this.count = count;
  107. }
  108. public List<?> getData() {
  109. return data;
  110. }
  111. public void setData(List<?> data) {
  112. this.data = data;
  113. }
  114. }

WxInitController.java - 微信初始化接入Controller控制器

  1. package net.javadog.springbootwexin.controller;
  2. import net.javadog.springbootwexin.common.AjaxJson;
  3. import net.javadog.springbootwexin.service.WxService;
  4. import net.javadog.springbootwexin.utils.WxUtil;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import org.springframework.web.bind.annotation.RequestParam;
  10. import org.springframework.web.bind.annotation.RestController;
  11. import java.util.Map;
  12. /**
  13. * 一个低端小气没档次的程序狗 JavaDog
  14. * blog.javadog.net
  15. *
  16. * @BelongsProject: springboot-wexin
  17. * @BelongsPackage: net.javadog.springbootwexin.controller
  18. * @Author: hdx
  19. * @CreateTime: 2020-02-14 14:52
  20. * @Description: 微信初始化接入Controller控制器
  21. */
  22. @RestController
  23. @RequestMapping("/weixin")
  24. public class WxInitController {
  25. protected Logger logger = LoggerFactory.getLogger(getClass());
  26. @Autowired
  27. private WxService wxService;
  28. /**
  29. *@Author: hdx
  30. *@CreateTime: 20:39 2020/2/14
  31. *@param: shareUrl 分享url地址
  32. *@Description: 初始化微信JSSDK Config信息
  33. 1.先通过appId和appSecret参数请求指定微信地址 获取AccessToken
  34. 2.在通过第一步中的AccessToken作为参数请求微信地址 获取jsapi_ticket临时票据(此处不考虑调用频率,使用者根据情况放入缓存或定时任务)
  35. 3.通过第二步的JssdkGetticket和timestamp,nonceStr,url作为参数请求微信地址,获取签名signature
  36. 4.将第三步获得的signature和jsapi_ticket,nonceStr,timestamp,url返回给前端,作为Config初始化验证的信息
  37. */
  38. @RequestMapping("/initWXJSSDKConfigInfo")
  39. public AjaxJson initWXJSConfig (@RequestParam(required = false) String url) throws Exception{
  40. logger.info("url=" + url);
  41. String json = "";
  42. try {
  43. Map map = wxService.initJSSDKConfig(url);
  44. json = WxUtil.mapToJson(map);
  45. }catch (Exception e){
  46. AjaxJson.fail(e.getMessage());
  47. }
  48. return AjaxJson.ok(json);
  49. }
  50. }

WxService.java - 初始化JSSDKConfig

  1. package net.javadog.springbootwexin.service;
  2. import lombok.Getter;
  3. import net.javadog.springbootwexin.utils.WxUtil;
  4. import org.springframework.beans.factory.annotation.Value;
  5. import org.springframework.stereotype.Service;
  6. import java.util.HashMap;
  7. import java.util.Map;
  8. import java.util.UUID;
  9. /**
  10. * 一个低端小气没档次的程序狗 JavaDog
  11. * blog.javadog.net
  12. *
  13. * @BelongsProject: springboot-wexin
  14. * @BelongsPackage: net.javadog.springbootwexin.service
  15. * @Author: hdx
  16. * @CreateTime: 2020-02-14 20:43
  17. * @Description: 微信相关service
  18. */
  19. @Service
  20. public class WxService {
  21. @Getter
  22. private static String AppId;
  23. @Value("${wx.appId}")
  24. public void setAppId(String appId) {
  25. AppId = appId;
  26. }
  27. /**
  28. *@Author: hdx
  29. *@CreateTime: 20:46 2020/2/14
  30. *@param: shareUrl 分享的url
  31. *@Description: 初始化JSSDKConfig
  32. */
  33. public Map initJSSDKConfig(String url) throws Exception {
  34. //获取AccessToken
  35. String accessToken = WxUtil.getJSSDKAccessToken();
  36. //获取JssdkGetticket
  37. String jsapiTicket = WxUtil.getJssdkGetticket(accessToken);
  38. String timestamp = Long.toString(System.currentTimeMillis() / 1000);
  39. String nonceStr = UUID.randomUUID().toString();
  40. String signature = WxUtil.buildJSSDKSignature(jsapiTicket,timestamp,nonceStr,url);
  41. Map<String,String> map = new HashMap<String,String>();
  42. map.put("url", url);
  43. map.put("jsapi_ticket", jsapiTicket);
  44. map.put("nonceStr", nonceStr);
  45. map.put("timestamp", timestamp);
  46. map.put("signature", signature);
  47. map.put("appid", AppId);
  48. return map;
  49. }
  50. }

WxUtil.java - 微信工具类

  1. package net.javadog.springbootwexin.utils;
  2. import com.google.gson.Gson;
  3. import com.google.gson.reflect.TypeToken;
  4. import lombok.Getter;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.http.ResponseEntity;
  7. import org.springframework.stereotype.Component;
  8. import org.springframework.web.client.RestTemplate;
  9. import java.security.MessageDigest;
  10. import java.util.Map;
  11. /**
  12. * 一个低端小气没档次的程序狗 JavaDog
  13. * blog.javadog.net
  14. *
  15. * @BelongsProject: springboot-wexin
  16. * @BelongsPackage: net.javadog.springbootwexin.utils
  17. * @Author: hdx
  18. * @CreateTime: 2020-02-14 21:19
  19. * @Description: 微信工具类
  20. */
  21. @Component
  22. public class WxUtil {
  23. @Getter
  24. protected static String AppId;
  25. @Getter
  26. protected static String AppSecret;
  27. @Getter
  28. protected static String JssdkAccesstokenUrl;
  29. @Getter
  30. protected static String JssdkGetticketUrl;
  31. @Value("${wx.appId}")
  32. public void setAppId(String appId) {
  33. AppId = appId;
  34. }
  35. @Value("${wx.appSecret}")
  36. public void setAppSecret(String appSecret) {
  37. AppSecret = appSecret;
  38. }
  39. @Value("${wx.jssdk_accesstoken_url}")
  40. public void setJssdkAccesstokenUrl(String jssdkAccesstokenUrl) {
  41. JssdkAccesstokenUrl = jssdkAccesstokenUrl;
  42. }
  43. @Value("${wx.jssdk_getticket_url}")
  44. public void setJssdkGetticketUrl(String jssdkGetticketUrl) {
  45. JssdkGetticketUrl = jssdkGetticketUrl;
  46. }
  47. /**
  48. *@Author: hdx
  49. *@CreateTime: 21:31 2020/2/14
  50. *@param: * @param null
  51. *@Description:
  52. */
  53. public static String getJSSDKAccessToken() {
  54. String token = null;
  55. String url = JssdkAccesstokenUrl.replaceAll("APPID",
  56. AppId).replaceAll("APPSECRET",
  57. AppSecret);
  58. String json = postRequestForWeiXinService(url);
  59. Map map = jsonToMap(json);
  60. if (map != null) {
  61. token = (String) map.get("access_token");
  62. }
  63. return token;
  64. }
  65. /**
  66. *@Author: hdx
  67. *@CreateTime: 21:40 2020/2/14
  68. *@param: * @param null
  69. *@Description: 根据accessToken获取JssdkGetticket
  70. */
  71. public static String getJssdkGetticket(String accessToken) {
  72. String url = JssdkGetticketUrl.replaceAll("ACCESS_TOKEN", accessToken);
  73. String json = postRequestForWeiXinService(url);
  74. Map map = jsonToMap(json);
  75. String jsapi_ticket = null;
  76. if (map != null) {
  77. jsapi_ticket = (String) map.get("ticket");
  78. }
  79. return jsapi_ticket;
  80. }
  81. /**
  82. *@Author: hdx
  83. *@CreateTime: 21:41 2020/2/14
  84. *@param:ticket 根据accessToken生成的JssdkGetticket
  85. *@param:timestamp 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
  86. *@param:nonceStr 随机字符串
  87. *@param:url 当前网页的URL
  88. *@Description: 构建分享链接的签名
  89. */
  90. public static String buildJSSDKSignature(String ticket,String timestamp,String nonceStr ,String url) throws Exception {
  91. String orderedString = "jsapi_ticket=" + ticket
  92. + "&noncestr=" + nonceStr + "&timestamp=" + timestamp
  93. + "&url=" + url;
  94. return sha1(orderedString);
  95. }
  96. /**
  97. * sha1 加密JSSDK微信配置参数获取签名。
  98. *
  99. * @return
  100. */
  101. public static String sha1(String orderedString) throws Exception {
  102. String ciphertext = null;
  103. MessageDigest md = MessageDigest.getInstance("SHA-1");
  104. byte[] digest = md.digest(orderedString.getBytes());
  105. ciphertext = byteToStr(digest);
  106. return ciphertext.toLowerCase();
  107. }
  108. /**
  109. * 将字节数组转换为十六进制字符串
  110. *
  111. * @param byteArray
  112. * @return
  113. */
  114. private static String byteToStr(byte[] byteArray) {
  115. String strDigest = "";
  116. for (int i = 0; i < byteArray.length; i++) {
  117. strDigest += byteToHexStr(byteArray[i]);
  118. }
  119. return strDigest;
  120. }
  121. /**
  122. * 将字节转换为十六进制字符串
  123. *
  124. * @param mByte
  125. * @return
  126. */
  127. private static String byteToHexStr(byte mByte) {
  128. char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  129. char[] tempArr = new char[2];
  130. tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
  131. tempArr[1] = Digit[mByte & 0X0F];
  132. String s = new String(tempArr);
  133. return s;
  134. }
  135. /**
  136. *@Author: hdx
  137. *@CreateTime: 21:49 2020/2/14
  138. *@param: map
  139. *@Description: mapToJson
  140. */
  141. public static String mapToJson(Map map){
  142. Gson gson = new Gson();
  143. String json = gson.toJson(map);
  144. return json;
  145. }
  146. /**
  147. *@Author: hdx
  148. *@CreateTime: 21:37 2020/2/14
  149. *@param: json
  150. *@Description: jsonToMap
  151. */
  152. private static Map jsonToMap(String json) {
  153. Gson gons = new Gson();
  154. Map map = gons.fromJson(json, new TypeToken<Map>(){}.getType());
  155. return map;
  156. }
  157. /**
  158. *@Author: hdx
  159. *@CreateTime: 21:36 2020/2/14
  160. *@param: * @param null
  161. *@Description: 调取微信接口
  162. */
  163. private static String postRequestForWeiXinService(String getAccessTokenUrl) {
  164. RestTemplate restTemplate = new RestTemplate();
  165. ResponseEntity<String> postForEntity = restTemplate.postForEntity(getAccessTokenUrl, null, String.class);
  166. String json = postForEntity.getBody();
  167. return json;
  168. }
  169. }

SpringbootWexinApplication.java - SpringBoot启动类

  1. package net.javadog.springbootwexin;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class SpringbootWexinApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(SpringbootWexinApplication.class, args);
  8. }
  9. }

config/application.yml - 基础配置文件

  1. spring:
  2. profiles:
  3. #激活配置文件
  4. active: prod
  5. #配置静态资源路径
  6. resources:
  7. static-locations: classpath:/static/
  8. #日志相关
  9. logging:
  10. #配置文件日志路径
  11. config: classpath:logback-spring.xml
  12. #微信相关配置
  13. wx:
  14. #appId (到时候换成自己公众号的)
  15. appId: wx4ad618620f8c3528
  16. #appSecret(到时候换成自己公众号的)
  17. appSecret: b772c7863b29e270aa86e40f9b9e6215
  18. #参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token)
  19. jssdk_accesstoken_url: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
  20. #用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket)
  21. jssdk_getticket_url: https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

application-dev.yml -开发配置文件(可选)

  1. # 开发环境配置
  2. spring:
  3. profiles: dev
  4. #端口设置
  5. server:
  6. port: 8000

application-prod.yml -生产配置文件(因JS接口安全域名限制,则采取正式生产配置)

  1. # 生产环境配置
  2. spring:
  3. profiles: prod
  4. #端口设置
  5. server:
  6. port: 8002

application-test.yml -测试配置文件(可选)

  1. # 生产环境配置
  2. spring:
  3. profiles: prod
  4. #端口设置
  5. server:
  6. port: 8002

**demo.html ** - 测试h5页面

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>测试jssdk</title>
  8. <!--引入微信JS文件-->
  9. <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript"></script>
  10. <!--引入jquery-->
  11. <script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>
  12. <script>
  13. //获取当前页面地址
  14. var url = (window.location.href).split('#')[0];
  15. //调取后台接口获取权限验证配置
  16. $.ajax({
  17. type : "get",
  18. /*!!!切记到时候改成自己的*/
  19. url : "http://wxjssdk.javadog.net/weixin/initWXJSSDKConfigInfo?url="+url,//替换网址,xxx根据自己jssdk文件位置修改
  20. success : function(data){
  21. console.log("返回值为=" + data);
  22. var msg = "";
  23. if(data.success){
  24. msg = JSON.parse(data.msg);
  25. }
  26. //通过config接口注入权限验证配置
  27. wx.config({
  28. debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
  29. appId: msg.appid,
  30. timestamp: msg.timestamp,
  31. nonceStr: msg.nonceStr,
  32. signature: msg.signature,
  33. /*!!!切记到时候按需自己选择,参考文档填写*/
  34. jsApiList: [
  35. "onMenuShareAppMessage",//分享给好友
  36. "chooseImage"
  37. ]
  38. });
  39. },
  40. error:function(data){
  41. alert(JSON.stringify(data));
  42. }
  43. });
  44. //通过ready接口处理成功验证
  45. wx.ready(function (){
  46. wx.checkJsApi({
  47. jsApiList: ['chooseImage','onMenuShareAppMessage'],
  48. success: function (res) {JSON.stringify(res)}
  49. });
  50. var shareData = {
  51. title: '标题',
  52. desc: '简介',//这里请特别注意是要去除html
  53. link: url,
  54. imgUrl: 'http://b2b.haier.com/shop/userfiles/sys/1/files/201912/af656b3a-8c2c-424d-937b-a8035deb78f5.jpg'
  55. };
  56. wx.onMenuShareAppMessage(shareData);
  57. });
  58. //从相册选取图片
  59. function wxchooseImage(){
  60. wx.chooseImage({
  61. count: 1, // 默认9
  62. sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
  63. sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
  64. success: function (res) {
  65. var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
  66. }
  67. });
  68. }
  69. </script>
  70. </head>
  71. <body>
  72. <button onclick="wxchooseImage();">点我选取相册</button>
  73. </body>
  74. </html>

??nginx 配置,此处不是项目中的代码!!!
nginx.config - nginx服务器配置

  1. server
  2. {
  3. listen 80; #监听端口设为 80。
  4. server_name wxjssdk.javadog.net; #请绑定自己的前缀域名。
  5. location / {
  6. proxy_set_header HOST $host;
  7. proxy_set_header X-Forwarded-Proto $scheme;
  8. proxy_set_header X-Real-IP $remote_addr;
  9. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  10. proxy_pass http://127.0.0.1:8002/;
  11. }
  12. }

MP_verify_B0vMQLCguxRzP1Rc.txt - JS接口安全域名验证文件(到时候替换成自己公众号上的),必须在域名根路径下可以访问

  1. #一定把自己公众号上的txt验证文件放上!!!
  2. B0vMQLCguxRzP1Rc

步骤详解

打开文档JSSDK使用步骤段落,如下??
在这里插入图片描述

1.绑定域名

在这里插入图片描述
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。如下??
在这里插入图片描述
点击设置如下??
在这里插入图片描述

关键点
  • 1.只能是三个域名或路径,中文,ip,带端口等路径均不可
  • 2.域名必须是ICP备案过的,有些同学使用内网穿透花生壳之类的无法设置JS安全域名
  • 3.必须将txt文件放置安全域名所对应的目录,如wxjssdk.javadog.net/xxx.txt。可由nginx配置,只要能访问即可,如果访问不到则无法设置JS安全域名
2.引入JS文件

在这里插入图片描述
实际引用在我们的项目Demo.html页面中第9行,如

3.通过config接口注入权限验证配置

在这里插入图片描述

关键点

必须在后台开放一个对外获取config接口注入权限的接口
对应我们代码中WxInitController.java 中的initWXJSSDKConfigInfo()方法,会返回文档中所需的必填项appId,timestamp,nonceStr,signature验证参数
在这里插入图片描述

实现步骤
  1. 1.先通过appIdappSecret参数请求指定微信地址 获取AccessToken
  2. 2.在通过第一步中的AccessToken作为参数请求微信地址 获取jsapi_ticket临时票据(此处不考虑调用频率,使用者根据情况放入缓存或定时任务)
  3. 3.通过第二步的JssdkGettickettimestamp,nonceStr,url作为参数请求微信地址,获取签名signature
  4. 4.将第三步获得的signaturejsapi_ticket,nonceStr,timestamp,url返回给前端,作为Config初始化验证的信息

在这里插入图片描述

  • 1.先通过appId和appSecret参数请求指定微信地址 获取AccessToken
    对应我们代码中WxUtil.java第61行getJSSDKAccessToken()方法
    在这里插入图片描述
    通过自己公众号的appId和appSecret调用微信服务器access_token接口地址获取token,地址如下
    https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
    将其中APPID和APPSECRET替换成自己公众号的appId和appSecret,调取后返回Json字符串结果,获取access_token

  • 2.通过第一步中的AccessToken作为参数请求微信地址 获取jsapi_ticket临时票据
    对应我们代码中WxUtil.java第81行getJssdkGetticket()方法
    在这里插入图片描述
    通过上一步获得的access_token调用微信服务器jsapi_ticket接口地址获取jsapi_ticket,地址如下
    https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
    将其中ACCESS_TOKEN替换成上一步获取的access_token,调取后返回Json字符串结果,获取jsapi_ticket

  • 3.通过第二步的JssdkGetticket和timestamp,nonceStr,url作为参数请求微信地址,获取签名signature
    对应我们代码中WxUtil.java第102行buildJSSDKSignature()方法
    在这里插入图片描述
    通过上一步获得的jsapi_ticket,加上timestamp(支付签名时间戳),nonceStr(随机字符串),url(当前网页的URL),按照字段名的ASCII 码从小到大排序(字典序)后通过sha1进行签名,生成最终签名数据。
    对应我们代码中WxUtil.java第115行sha1()方法
    在这里插入图片描述

  • 4.前端成功接到返回值

对应我们代码中demo.html第16行$.ajax方法
在这里插入图片描述
接口返回值为
在这里插入图片描述
JSON.parse(msg)转化一下JSON对象,对应我们代码中的Demo.html中24行,转化后数据做wx.config接口注入权限验证,对应我们代码demo.html第37行
在这里插入图片描述

4.通过ready接口处理成功验证

在这里插入图片描述

关键点

所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行
在我们代码在demo.html第46行,自定义分享接口,需要在页面初始化加载时就放入ready才可生效
在这里插入图片描述
反之不需要初始化加载的即可通过用户事件触发执行即可
在我们代码在demo.html第63行,用户点击按钮触发-拍照或从手机相册中选图接口
在这里插入图片描述

发布

我采用的IDEA插件Alibaba Cloud Toolkit工具一键部署本地应用到ECS服务器,可百度或等我下篇文章详解一下这个插件的用法。
在这里插入图片描述
在这里插入图片描述
Target ECS:目标服务器,我买的是阿里的服务器,则直接可以搜索到。
Target Directory: 目标目录,需要把打成的jar包上传至哪个路径下 如:/usr/local/hdx/web/
Command: 上传后执行的操作命令 如:nohup java -jar /usr/local/hdx/web/springboot-wexin.jar

发布成功后会在终端出现成功提示信息
在这里插入图片描述
然后大功告成,访问一下试试 http://wxjssdk.javadog.net/demo.html
如果调试推荐使用微信开发者工具,也就是
在这里插入图片描述
切记配置nginx服务器安全端口访问权限!!!否则会404哦!!!

测试

  • 1.先来测试下拍照或从手机相册中选图接口
    在这里插入图片描述
    调试正常

  • 2.再来测试微信内置分享
    在这里插入图片描述
    调试报错,这是个小坑。本狗在这调试了好久,原因出在个人的订阅号是没有自定义分享权限的!!
    在这里插入图片描述

小坑总结

  1. 订阅号和服务号所涉及权限不同,需详细查看微信开发文档,查询公众号权限
  2. IP白名单未设置,会报40164
    在这里插入图片描述
    IP白名单需要在公众号安全中心设置
    在这里插入图片描述
  3. invalid signature 签名异常
    建议使用微信JSSDK签名验证工具验证是否有误

我是JavaDog,谢谢博友耐心看完, 抽空来我狗窝??瞅瞅呗 blog.javadog.net

原文链接:https://www.cnblogs.com/javadog-net/p/17245344.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号