当前位置:   article > 正文

java版--微信jssdk 授权config接口注入权限验证配置的参数获取+全局缓存access_token和jsapi_ticket_java接入微信js-sdk

java接入微信js-sdk

java版–微信jssdk 授权config接口注入权限验证配置的参数获取+全局缓存access_token和jsapi_ticket

最近的开发公众号h5,需要用的微信的扫一扫,不过微信这些功能,需要先通过config接口注入权限验证配置,翻了好多文章才弄出来,下面开始吧

JSSDK使用步骤

步骤一:绑定域名
步骤二:引入JS文件
这些我就不说了,这些微信官网都有:: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html.
我们直接开始第三步

一,授权config接口注入权限验证配置的参数获取

1.获取access_token+获取ticket

下面是获取access_token获取ticket的方法,(这里要说一下获取ticket是需要用到获取的access_token),我把这两个方法都封装到一个WeixinUtil 实体类,具体代码如下:

import com.hg.wrg.modules.qt.qtutil.MdzwUtils;
import com.hg.wrg.modules.qt.qtutil.PayConfig;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.util.Map;

public class WeixinUtil {
    //获取access_token
    public  static  String getAccessToken(){
        StringBuilder url = new StringBuilder("https://api.weixin.qq.com/cgi-bin/token?");
        url.append("grant_type=");//grant_type设置
        url.append("client_credential");
        url.append("&appid=");//appid设置
        url.append("appid");//填写自己的公众号APPID
        url.append("&secret=");//secret设置
        url.append("secret");//secret
        Map<String, Object> map = null;
        try {
            HttpClient client = HttpClientBuilder.create().build();//构建一个Client
            HttpGet get = new HttpGet(url.toString());    //构建一个GET请求
            HttpResponse response = client.execute(get);//提交GET请求
            HttpEntity result = response.getEntity();//拿到返回的HttpResponse的"实体"
            String content = EntityUtils.toString(result);
            System.out.println(content);//打印返回的信息
            JSONObject res = JSONObject.fromObject(content);//把信息封装为json*/
            //把信息封装到map
            map = MdzwUtils.parseJSON2Map(res);//这个小工具的代码在下面
            System.out.println(map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map.get("access_token").toString();

    }
    //获取ticket
    public  static  String getJsApiTicket(String accessToken){
        StringBuilder url = new StringBuilder("https://api.weixin.qq.com/cgi-bin/ticket/getticket?");
        url.append("access_token=");//code设置
        url.append(accessToken);//获取的access_token
        url.append("&type=");//appid设置
        url.append("jsapi");

        Map<String, Object> map = null;
        try {
            HttpClient client = HttpClientBuilder.create().build();//构建一个Client
            HttpGet get = new HttpGet(url.toString());    //构建一个GET请求
            HttpResponse response = client.execute(get);//提交GET请求
            HttpEntity result = response.getEntity();//拿到返回的HttpResponse的"实体"
            String content = EntityUtils.toString(result);
            System.out.println(content);//打印返回的信息
            JSONObject res = JSONObject.fromObject(content);//把信息封装为json*/
            //把信息封装到map
            map = MdzwUtils.parseJSON2Map(res);//这个小工具的代码在下面
            System.out.println(map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map.get("ticket").toString();

    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

json转map,这个小工具


import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.util.*;

public class MdzwUtils {
    //json转map,这个小工具是我从网上找的,谢谢作者

    public static Map<String, Object> parseJSON2Map(JSONObject json) {
        Map<String, Object> map = new HashMap<String, Object>();
        // 最外层解析
        for (Object k : json.keySet()) {
            Object v = json.get(k);
            // 如果内层还是数组的话,继续解析
            if (v instanceof JSONArray) {
                List<Map<String, Object>> list = new ArrayList<>();
                @SuppressWarnings("unchecked")
                Iterator<JSONObject> it = ((JSONArray) v).iterator();
                while (it.hasNext()) {
                    JSONObject json2 = it.next();
                    list.add(parseJSON2Map(json2));
                }
                map.put(k.toString(), list);
            } else {
                map.put(k.toString(), v);
            }
        }
        return map;
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

2.生成JS-SDK权限验证的签名

获得jsapi_ticket之后,我们就可以就可以生成JS-SDK权限验证的签名了。
微信
DEMO页面: https://www.weixinsxy.com/jssdk/

示例代码:
http://demo.open.weixin.qq.com/jssdk/sample.zip
备注:链接中包含php、java、nodejs以及python的示例代码供第三方参考,第三方切记要对获取的accesstoken以及jsapi_ticket进行缓存以确保不会触发频率限制。

我这里是把微信官方给的dome稍微修改一下;
下附代码:


import java.util.UUID;
import java.util.Map;
import java.util.HashMap;
import java.util.Formatter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;

/**
 * 官方给的使用js的验证工具
 */
public class JsSignUtil {
    public static String accessToken = null;

    public static Map<String, String> sign(String url) throws Exception{
        accessToken = WxAccessToken.getSavedAccessToken();
        String jsapi_ticket = WxAccessToken.getSavedJsApiTicket(accessToken);


        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + nonce_str +
                "&timestamp=" + timestamp +
                "&url=" + url;
        System.out.println("string1="+string1);

        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        ret.put("appId", "appid");//公众号appid

        System.out.println("1.ticket(原始)="+jsapi_ticket);
        System.out.println("2.url="+ret.get("url"));
        System.out.println("3.jsapi_ticket(处理后)="+ret.get("jsapi_ticket"));
        System.out.println("4.nonceStr="+ret.get("nonceStr"));
        System.out.println("5.signature="+ret.get("signature"));
        System.out.println("6.timestamp="+ret.get("timestamp"));

        return ret;
    }


    /**
     * 随机加密
     * @param hash
     * @return
     */
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    /**
     * 产生随机串--由程序自己随机产生
     * @return
     */
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    /**
     * 由程序自己获取当前时间
     * @return
     */
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99

由于access_token和jsapi_ticket的有效期都是7200秒,且每天的请求次数有限所以我们需要把access_token和jsapi_ticket缓存起来

二,全局缓存access_token和jsapi_ticket

我这里用的是本地文件缓存,通过物理磁盘创建txt文件保存。
其他的缓存方式最后会附上连接文章,有兴趣的可以自行观看。

首先建一个 AccessToken实体类用于组装返回结果,
我是用IDEA编写
这里用了lombok插件,没用的可以自行添加get,set,和构造方法

import lombok.Data;

import java.io.Serializable;

/**
 * AccessToken实体类用于组装返回结果
 */
@Data
public class AccessToken implements Serializable {
    private String token;
    private Integer expiresIn;
    private String jsApiTicket;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这里依赖google的Gson jar包,如果是maven项目,下面是方式依赖

<dependency>  
    <groupId>com.google.code.gson</groupId>  
    <artifactId>gson</artifactId>  
    <version>2.7</version>  
</dependency> 
  • 1
  • 2
  • 3
  • 4
  • 5

本地缓存的具体代码,里面都有注释
可以用main方法测试

import com.google.gson.Gson;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 *
 * 微信获取AccessToken并本地保存
 */
public class WxAccessToken {
    private static final long MAX_TIME = 7000;// 微信允许最长Access_token有效时间为7200秒,这里设置为7000秒

    public static String access_token_obj=null;
    /**
     * 获取Access_token 保存并且只保存2小时Access_token。如果超过两个小时重新获取;如果没有超过两个小时,直接获取
     * 思路:将获取到的Access_token和当前时间存储到file里,
     * 取出时判断当前时间和存储里面的记录的时间的时间差,如果大于MAX_TIME,重新获取,并且将获取到的存储到file替换原来的内容
     * 如果小于MAX_TIME,直接获取。
     */
    public static String getSavedAccessToken() throws IOException {
        Gson gson = new Gson();
        String mAccess_token = null;// 需要获取的Access_token;
        System.out.println(System.getProperty("user.di"));
        File file = new File("D:/weixin/weixinAccess_token.txt");// Access_token保存的位置
        // 如果文件不存在,创建
        if (!file.exists())
            file.createNewFile();
        // 如果文件大小等于0,说明第一次使用,存入Access_token

        if (file.length() == 0) {
            System.out.println("如果文件大小等于0,说明第一次使用,存入Access_token");
           // access_token_obj = WeixinUtil.getAccessToken();
            String token = WeixinUtil.getAccessToken();
            FileOutputStream fos = new FileOutputStream("D:/weixin/weixinAccess_token.txt", false);// 不允许追加
            AccessToken at = new AccessToken();
            at.setToken(token);
            at.setExpiresIn(Integer.valueOf(System.currentTimeMillis()/1000+""));
            System.out.println("at"+at);
            mAccess_token=token;
            String json = gson.toJson(at);
            fos.write(json.getBytes());
            fos.close();
        } else {
            System.out.println("读取文件内容");
            // 读取文件内容
            FileInputStream fis = new FileInputStream(file);
            byte[] b = new byte[2048];
            int len = fis.read(b);
            String mJsonAccess_token = new String(b, 0, len);// 读取到的文件内容
            System.out.println("读取到的文件内容"+mJsonAccess_token);
            AccessToken access_token = gson.fromJson(mJsonAccess_token, new AccessToken().getClass());
            if (access_token.getExpiresIn() != null) {
                System.out.println("access_token.getExpiresIn()"+access_token.getExpiresIn());

                long lastSaveTime = access_token.getExpiresIn();
                long nowTime = System.currentTimeMillis()/1000;
                long remianTime = nowTime - lastSaveTime;
             
                System.out.println("lastSaveTime"+lastSaveTime);
                System.out.println("nowTime"+nowTime);
                System.out.println("remianTime"+remianTime);
                System.out.println(remianTime < MAX_TIME);
                if (remianTime < MAX_TIME) {

                    AccessToken access = gson.fromJson(mJsonAccess_token, new AccessToken().getClass());
                    mAccess_token = access.getToken();
                    System.out.println("读取的mAccess_token"+mAccess_token);
                } else {
                    System.out.println("更新mJsonAccess_token");
                   // access_token_obj = WeiXinUtil.getToken();
                    FileOutputStream fos = new FileOutputStream(file, false);// 不允许追加
                    AccessToken newToken = new AccessToken();
                    String token=WeixinUtil.getAccessToken();
                    newToken.setToken(token);
                    newToken.setExpiresIn(Integer.valueOf(System.currentTimeMillis()/1000+""));
                    mAccess_token=token;
                    String json = gson.toJson(newToken);
                    fos.write((json).getBytes());
                    fos.close();
                }
            }
        }
        System.out.println("返回的mAccess_token"+mAccess_token);
        return mAccess_token;
    }

    /**
     * 获取JsApiTicket 保存并且只保存2小时JsApiTicket。如果超过两个小时重新获取;如果没有超过两个小时,直接获取
     * 思路:将获取到的JsApiTicket和当前时间存储到file里,
     * 取出时判断当前时间和存储里面的记录的时间的时间差,如果大于MAX_TIME,重新获取,并且将获取到的存储到file替换原来的内容
     * 如果小于MAX_TIME,直接获取。
     */
    public static String getSavedJsApiTicket(String accessToken) throws IOException {
        Gson gson = new Gson();
        String mJsApiTicket = null;// 需要获取的Access_token;
        System.out.println(System.getProperty("user.di"));
        File file = new File("D:/weixin/weixinJsApiTicket.txt");// Access_token保存的位置
        // 如果文件不存在,创建
        if (!file.exists())
            file.createNewFile();
        // 如果文件大小等于0,说明第一次使用,存入Access_token

        if (file.length() == 0) {
            System.out.println("如果文件大小等于0,说明第一次使用,存入JsApiTicket");
            // access_token_obj = WeixinUtil.getAccessToken();
            String aJsApiTicket = WeixinUtil.getJsApiTicket(accessToken);
            FileOutputStream fos = new FileOutputStream("D:/weixin/weixinJsApiTicket.txt", false);// 不允许追加
            AccessToken at = new AccessToken();
            at.setJsApiTicket(aJsApiTicket);
            at.setExpiresIn(Integer.valueOf(System.currentTimeMillis()/1000+""));
            System.out.println("at"+at);
            mJsApiTicket=aJsApiTicket;
            String json = gson.toJson(at);
            fos.write(json.getBytes());
            fos.close();
        } else {
            System.out.println("读取文件内容");
            // 读取文件内容
            FileInputStream fis = new FileInputStream(file);
            byte[] b = new byte[2048];
            int len = fis.read(b);
            String mJsonjsApiTicket = new String(b, 0, len);// 读取到的文件内容
            System.out.println("读取到的文件内容"+mJsonjsApiTicket);
            AccessToken jsApiTicket = gson.fromJson(mJsonjsApiTicket, new AccessToken().getClass());
            if (jsApiTicket.getExpiresIn() != null) {
                System.out.println("access_token.getExpiresIn()"+jsApiTicket.getExpiresIn());

                long lastSaveTime = jsApiTicket.getExpiresIn();
                long nowTime = System.currentTimeMillis()/1000;
                long remianTime = nowTime - lastSaveTime;
              
                System.out.println("lastSaveTime"+lastSaveTime);
                System.out.println("nowTime"+nowTime);
                System.out.println("remianTime"+remianTime);
                System.out.println(remianTime < MAX_TIME);
                if (remianTime < MAX_TIME) {

                    AccessToken access = gson.fromJson(mJsonjsApiTicket, new AccessToken().getClass());
                    mJsApiTicket = access.getJsApiTicket();
                    System.out.println("读取的JsApiTicket"+jsApiTicket);
                } else {
                    System.out.println("更新JsApiTicket");
                    // access_token_obj = WeiXinUtil.getToken();
                    FileOutputStream fos = new FileOutputStream(file, false);// 不允许追加
                    AccessToken newJsApiTicket = new AccessToken();
                    String jsapiTicket=WeixinUtil.getJsApiTicket(accessToken);
                    newJsApiTicket.setJsApiTicket(jsapiTicket);
                    newJsApiTicket.setExpiresIn(Integer.valueOf(System.currentTimeMillis()/1000+""));
                    mJsApiTicket=jsapiTicket;
                    String json = gson.toJson(newJsApiTicket);
                    fos.write((json).getBytes());
                    fos.close();
                }
            }
        }
        System.out.println("返回的JsApiTicket"+mJsApiTicket);
        return mJsApiTicket;
    }

    public static void main(String args[]) throws IOException {
        WxAccessToken.getSavedJsApiTicket(WxAccessToken.getSavedAccessToken());
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164

本地缓存我是参考–>其他缓存的连接写的

以上就是java版–微信jssdk 授权config接口注入权限验证配置的参数获取+全局缓存access_token和jsapi_ticket的全部内容,请大家多多关照

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/598844
推荐阅读
相关标签
  

闽ICP备14008679号