欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java接入微信JS-SDK

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

      在微信公众号开发中不可,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 }