微信JSSDK开发JAVA版实现

JSSDK JAVA开发第一步:绑定域名

先登录微信公众平台进入“公众号设置”(作者:在页面左下角,认证订阅号,认证服务号皆可配置)

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

set.jpg

再选择页面上方“功能设置”

1.jpg

这时可以看到“JS接口安全域名”。点击设置弹出以下输入框,按照要求填写域名(注意:IP不可用)

如:www.ipastimes.com, ipastimes.com,  examples.ipastimes.com 可用

2.jpg

JSSDK JAVA开发第二步:引入微信JS

    在需要引用微信JS接口的页面引入微信js文件(微信在其浏览器内置wx对象)http://res.wx.qq.com/open/js/jweixin-1.0.0.js

JSSDK JAVA开发第三步:后台实现签名逻辑

    1.获取access_token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
     /**
      * 获取接口访问凭证
     
      * @param appid 凭证
      * @param appsecret 密钥
      * @return
      */
     public  static  String getAccess_token(String appid, String appsecret) {
             //凭证获取(GET)
         String requestUrl = token_url.replace( "APPID" , appid).replace( "APPSECRET" , appsecret);
         // 发起GET请求获取凭证
         JSONObject jsonObject = httpsRequest(requestUrl,  "GET" null );
                 String access_token =  null ;
         if  ( null  != jsonObject) {
             try  {
                 access_token = jsonObject.getString( "access_token" );
             catch  (JSONException e) {
                 // 获取token失败
                 log.error( "获取token失败 errcode:{} errmsg:{}" , jsonObject.getInt( "errcode" ), jsonObject.getString( "errmsg" ));
             }
         }
         return  access_token;
     }

    2.获取jsapi_ticket

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
      * 调用微信JS接口的临时票据
     
      * @param access_token 接口访问凭证
      * @return
      */
     public  static  String getJsApiTicket(String access_token) {
         String requestUrl = url.replace( "ACCESS_TOKEN" , access_token);
         // 发起GET请求获取凭证
         JSONObject jsonObject = httpsRequest(requestUrl,  "GET" null );
         String ticket =  null ;
         if  ( null  != jsonObject) {
             try  {
                 ticket = jsonObject.getString( "ticket" );
             catch  (JSONException e) {
                 // 获取token失败
                 log.error( "获取token失败 errcode:{} errmsg:{}" , jsonObject.getInt( "errcode" ), jsonObject.getString( "errmsg" ));
             }
         }
         return  ticket;
     }

3.实现签名逻辑(根据官方sample改)

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
import  java.io.UnsupportedEncodingException;
import  java.security.MessageDigest;
import  java.security.NoSuchAlgorithmException;
import  java.text.SimpleDateFormat;
import  java.util.Date;
import  java.util.Formatter;
import  java.util.HashMap;
import  java.util.Map;
import  java.util.UUID;
 
import  javax.servlet.http.HttpServletRequest;
 
import  net.sf.json.JSONObject;
 
import  org.apache.struts2.ServletActionContext;
 
public  class  PastUtil {
     public  static  Token token =  null ;
     public  static  String time =  null ;
     public  static  String jsapi_ticket =  null ;
     /**
     
      * @param appId   公账号appId
      * @param appSecret
      * @param url    当前网页的URL,不包含#及其后面部分
      * @return
      */
     public  static  String getParam(String appId,String appSecret){
         if (token ==  null ){
             token = CommonUtil.getToken(appId, appSecret);
             jsapi_ticket = CommonUtil.getJsApiTicket(token.getAccessToken());
             time = getTime();
         } else {
             if (!time.substring( 0 13 ).equals(getTime().substring( 0 13 ))){  //每小时刷新一次
                 token =  null ;
                 token = CommonUtil.getToken(appId, appSecret);
                 jsapi_ticket = CommonUtil.getJsApiTicket(token.getAccessToken());
                 time = getTime();
             }
         }
         
         String url = getUrl();
         
         Map<String, String> params = sign(jsapi_ticket, url);
         params.put( "appid" , appId);
         
         JSONObject jsonObject = JSONObject.fromObject(params);  
         String jsonStr = jsonObject.toString();
         System.out.println(jsonStr);
         return  jsonStr;
     }
     
     private  static  String getUrl(){
         HttpServletRequest request = ServletActionContext.getRequest();
         
         StringBuffer requestUrl = request.getRequestURL();
         
         String queryString = request.getQueryString();
         String url = requestUrl + "?" +queryString;
         return  url;
     }
     
     public  static  Map<String, String> sign(String jsapi_ticket, String url) {
         Map<String, String> ret =  new  HashMap<String, String>();
         String nonce_str = create_nonce_str();
         String timestamp = create_timestamp();
         String str;
         String signature =  "" ;
 
         //注意这里参数名必须全部小写,且必须有序
         str =  "jsapi_ticket="  + jsapi_ticket +
                   "&noncestr="  + nonce_str +
                   "&timestamp="  + timestamp +
                   "&url="  + url;
 
         try
         {
             MessageDigest crypt = MessageDigest.getInstance( "SHA-1" );
             crypt.reset();
             crypt.update(str.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);
 
         return  ret;
     }
 
     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;
     }
 
     private  static  String create_nonce_str() {
         return  UUID.randomUUID().toString();
     }
 
     private  static  String create_timestamp() {
         return  Long.toString(System.currentTimeMillis() /  1000 );
     }
     
     //获取当前系统时间 用来判断access_token是否过期
     public  static  String getTime(){
         Date dt= new  Date();
         SimpleDateFormat sdf = new  SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
         return  sdf.format(dt);
     }
}

大部分开发者在签名认证处出错,开启debug模式,当进入页面时会alert出如下信息:

1.jpg

按照如下步骤排错:

1.确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。

2.确认config中noncestr, timestamp与用以签名中的对应noncestr, timestamp一致。

3.确认url是页面完整的url,包括GET参数部分。

4.确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。

5.确保一定缓存access_token和jsapi_ticket,可以减少两次服务器请求加速体验外,还避免了触发频率限制,提高服务稳定性。

附JS SDK权限表

JSSDK 权限.jpg

更多信息请参考:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值