zoukankan      html  css  js  c++  java
  • java接入微信JS-SDK

          在微信公众号开发中不可,jssdk的接入虽然不是必须,但是根据业务需求我们还是可能用到,下面是自己整理的关于java接入的jssdk的方法,这里是记录关于接入微信JS-SDK的准备工作,关于接入JS-SDK的相关功能,官网有明确的说明https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html

    第一步:绑定域名

    先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。

    备注:登录后可在“开发者中心”查看对应的接口权限。

    第二步:引入JS文件

    在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.4.0.js

    如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.4.0.js (支持https)。

    备注:支持使用 AMD/CMD 标准模块加载方法加载

    第三步:通过config接口注入权限验证配置

    wx.config({
      debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
      appId: '', // 必填,公众号的唯一标识
      timestamp: , // 必填,生成签名的时间戳
      nonceStr: '', // 必填,生成签名的随机串
      signature: '',// 必填,签名
      jsApiList: [] // 必填,需要使用的JS接口列表
    });

    当你完成上面三个步骤时,就可以使用微信JS-SDK的功能了,上面的步骤设置都简单,就是config签名的信息获取有点麻烦,这里主要说明下签名的获取,权限签名算法在api有简单说明,这里简单说明下签名规则。签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分),其中noncestr可以通过生成随机uuid,时间戳可以直接获取当前时间的时间,这些实现没用任何难度,接下来比较复杂的是jsapi_ticket的获取。jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。access_token一般都是设置全局缓存的,在access_token有效期内可以继续使用,本实例中我们通过单例模式实现access_token的全局缓存,这个只适合单实例的服务,如果是多实例请自行修改成数据库或redies等方式进行全局缓存。当noncestr、jsapi_ticket、timestamp、url等数据获取完成后,按照noncestr=Wm3WZYTPz0wzccnW&jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&timestamp=14145874577&url=http://mp.weixin.qq.com?params=value 进行url拼接,然后进行SHA1既可以获取到签名。

    代码示例:

    1.承装access_token的实体类,因为access_token的有效期是7200秒,

     1 import java.util.*;
     2 
     3 public class Singleton {
     4     //缓存accessToken 的Map  ,map中包含 一个accessToken 和 缓存的时间戳
     5     //当然也可以分开成两个属性咯
     6     private Map<String, String> map = new HashMap<>();
     7 
     8     private Singleton() {
     9     }
    10 
    11     private static Singleton single = null;
    12 
    13     // 静态工厂方法
    14     public static Singleton getInstance() {
    15         if (single == null) {
    16             single = new Singleton();
    17         }
    18         return single;
    19     }
    20 
    21     public Map<String, String> getMap() {
    22         return map;
    23     }
    24 
    25     public void setMap(Map<String, String> map) {
    26         this.map = map;
    27     }
    28 
    29     public static Singleton getSingle() {
    30         return single;
    31     }
    32 
    33     public static void setSingle(Singleton single) {
    34         Singleton.single = single;
    35     }
    36 }

    获取 jsapi_ticket以及生成签名

    public class WxUtils {
    
        public static String appId = "微信公众号appid";
    
        public static String appSecret = "微信公众号appSecret ";
        //获取access_token的url
        public final static String js_api_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
    
        /**
         * 获取access_token
         *
         * @return
         */
        private static String getAccessToken() {
            String rel = "";
            Singleton singleton = Singleton.getInstance();
            Map<String, String> map = singleton.getMap();
            String time = map.get("access_token_time");
            String accessToken = map.get("access_token");
            Long nowDate = new Date().getTime();
            //这里设置过期时间 3000*1000就好了
            if (accessToken != null && time != null && nowDate - Long.parseLong(time) < 7200 * 1000) {
                rel = accessToken;
            } else {
                String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appId, appSecret);
                String result = HttpUtils.defaultGetMethod(url);
                if (StringUtils.isBlank(result)) {
                    return null;
                }
                JsonObject responseJsonObject = GsonUtils.parseToJsonObj(result);
                map.put("access_token_time", nowDate + "");
                map.put("access_token", GsonUtils.getString(responseJsonObject, "access_token"));
                rel = GsonUtils.getString(responseJsonObject, "access_token");
            }
            return rel;
        }
    
        private static String getJsapiTicket(String accessToken) {
            String rel = "";
            Singleton singleton = Singleton.getInstance();
            Map<String, String> map = singleton.getMap();
            String js_api_ticketn_time = map.get("js_api_ticketn_time");
            String ticket = map.get("ticket");
            Long nowDate = new Date().getTime();
            if (ticket != null && js_api_ticketn_time != null && nowDate - Long.parseLong(js_api_ticketn_time) < 7200 * 1000) {
                rel = ticket;
            } else {
                String url = js_api_ticket_url.replace("ACCESS_TOKEN", accessToken);
                String result = HttpUtils.defaultGetMethod(url);
                if (StringUtils.isBlank(result)) {
                    return null;
                }
                JsonObject responseJsonObject = GsonUtils.parseToJsonObj(result);
                map.put("js_api_ticketn_time", nowDate + "");
                map.put("ticket", GsonUtils.getString(responseJsonObject, "ticket"));
                rel = GsonUtils.getString(responseJsonObject, "ticket");
            }
            return rel;
        }
    
        public static Map getConfig(String url) {
            String accessToken = getAccessToken();
            String ticket = getJsapiTicket(accessToken);
            String nonceStr = create_nonce_str();
            String timestamp = create_timestamp();
            String string1 = "jsapi_ticket=" + ticket +
                    "&noncestr=" + nonceStr +
                    "&timestamp=" + timestamp +
                    "&url=" + url;
            Map<String, Object> map = new HashMap<>();
            map.put("appId", appId);
            map.put("timestamp", timestamp);
            map.put("nonceStr", nonceStr);
            map.put("signature", SHA1.encode(string1));
            return map;
        }
    
        private static String create_nonce_str() {
            return UUID.randomUUID().toString();
        }
    
        private static String create_timestamp() {
            return Long.toString(System.currentTimeMillis() / 1000);
        }
    
    
    
    }

    SHA1签名

    /*
     * 微信公众平台(JAVA) SDK
     *
     * Copyright (c) 2016, Ansitech Network Technology Co.,Ltd All rights reserved.
     * http://www.ansitech.com/weixin/sdk/
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    
    import java.security.MessageDigest;
    
    /**
     * <p>Title: SHA1算法</p>
     *
     * @author levi
     */
    public final class SHA1 {
    
        private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
                '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    
        /**
         * Takes the raw bytes from the digest and formats them correct.
         *
         * @param bytes the raw bytes from the digest.
         * @return the formatted bytes.
         */
        private static String getFormattedText(byte[] bytes) {
            int len = bytes.length;
            StringBuilder buf = new StringBuilder(len * 2);
            // 把密文转换成十六进制的字符串形式
            for (int j = 0; j < len; j++) {
                buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
                buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
            }
            return buf.toString();
        }
    
        public static String encode(String str) {
            if (str == null) {
                return null;
            }
            try {
                MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
                messageDigest.update(str.getBytes());
                return getFormattedText(messageDigest.digest());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    通过上面的方法,我们已经准备好了接入微信JS-SDK的所有材料,那么怎么在前端那边使用,我们只需要请求到后台获取到config的相关数据就可以了。初次接入建议打开debug为调试模式,在debug调试模式打开的情况下接入成功会弹出成功提示。

     1 $(function () {
     2      wxConfig();//接入微信jssdk
     3 })
     4 
     5 //请求后台获取wxconfig需要的信息
     6 function  wxConfig() {
     7     $.ajax({
     8         url: '/pvmap-web/getData/wxConfig',
     9         type: 'get',
    10         data: {url: window.location.href},
    11         dataType: 'json',
    12         success: function (data) {
    13             // console.log(data)
    14             if (data.data != null || data.data != "") {
    15                 wx.config({
    16                     debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    17                     appId: data.data.appId, // 必填,公众号的唯一标识
    18                     timestamp: data.data.timestamp, // 必填,生成签名的时间戳
    19                     nonceStr: data.data.nonceStr, // 必填,生成签名的随机串
    20                     signature: data.data.signature,// 必填,签名
    21                     jsApiList: ['openLocation'] // 必填,需要使用的JS接口列表
    22                 });
    23             }
    24         },
    25         erroe: function (e) {
    26             console.log(e)
    27         }
    28     })
    29 }

     

  • 相关阅读:
    技术人员如何创业《四》- 打造超强执行力团队(转载)
    技术人员如何创业《一》—— 产品及想法(转载)
    一页纸商业计划书 (Business Plan) 模板(转载)
    公司项目架构的演变过程
    腾讯云CentOS 6.6安装 Nginx
    创业公司一年工作总结
    启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099的解决办法
    windows下使用批处理脚本实现多个版本的JDK切换
    Java后端WebSocket的Tomcat实现
    微信开发学习总结(三)——开发微信公众号的最基本功能——普通消息的接收和回复
  • 原文地址:https://www.cnblogs.com/lsyverygood/p/11989386.html
Copyright © 2011-2022 走看看