微信 JSSDK中Config配置    java版

公司让我搞微信开发 踩了很多坑,随手记下方便以后查看。微信JS-SDK是微信 公众平台面向网页开发者提供的基于微信内的网页开发工具包,通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验;本篇将面向网页开发者介绍微信JS-SDK如何使用及相关注意事项!JSSDK使用步骤:

步骤一:在微信公众平台绑定安全域名

步骤二:后端接口实现JS-SDK配置需要的参数

步骤三:页面实现JS-SDk中config的注入配置,并实现对成功和失败的处理

(一)在微信公众平台绑定安全域名 

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”(如下图),如果需要使用支付类接口,需要确保支付目录在支付的安全域名下,否则将无法完成支付!(注:登录后可在“开发者中心”查看对应的接口权限)


 

微信接口配置  java 微信java sdk_微信公众平台

(二)后端接口实现JS-SDK配置需要的参数



wx.config({         


                    debug:           true          ,           // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。         


                    appId:           ''          ,           // 必填,公众号的唯一标识         


                    timestamp: ,           // 必填,生成签名的时间戳         


                    nonceStr:           ''          ,           // 必填,生成签名的随机串         


                    signature:           ''          ,          // 必填,签名,见附录1         


                    jsApiList: []           // 必填,需要使用的JS接口列表,所有JS接口列表见附录2         


          });




我们查看js-sdk的配置文档和以上的代码可以发现config的配置需要4个必不可少的参数appId、timestamp、nonceStr、signature,这里的signature就是我们生成的签名!

生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket ,所以这里我们将jsapi_ticket的获取放到定时任务中,因为它和token的生命周期是一致的,所以在这里我们将他们放到一起,将原有的定时任务中获取token的代码做如下修改:



package           com.dy.wechat.common;         


                    


          import           java.text.SimpleDateFormat;         


          import           java.util.Date;         


          import           java.util.HashMap;         


          import           java.util.Map;         


                    


          import           net.sf.json.JSONObject;         


                    


          import           com.cuiyongzhi.web.util.GlobalConstants;         


          import           com.cuiyongzhi.wechat.util.HttpUtils;         


                    


          /**         


                    *          


                    * @Description: 定时刷新access_token 和 ticket         


                    * @author jerry_hello         


                    * @date 2017年12月26日 15:24         


                    */         


          public           class           WeChatTask {         


                    /**         


                    * @Description: 任务执行体         


                    * @param @throws Exception         


                    * @author jerry_hello         


                    * @date 2017年12月26日 15:24         


                    */         


                    public           void           getToken_getTicket()           throws           Exception {         


                    Map<String, String> params =           new           HashMap<String, String>();         


                    //获取token执行体         


                    params.put(          "grant_type"          ,           "client_credential"          );         


                    params.put(          "appid"          , GlobalConstants.getInterfaceUrl(          "appid"          ));         


                    params.put(          "secret"          , GlobalConstants.getInterfaceUrl(          "AppSecret"          ));         


                    String jstoken = HttpUtils.sendGet(         


                    GlobalConstants.getInterfaceUrl(          "tokenUrl"          ), params);         


                    String access_token = JSONObject.fromObject(jstoken).getString(         


                    "access_token"          );           // 获取到token并赋值保存         


                    GlobalConstants.interfaceUrlProperties.put(          "access_token"          , access_token);         


                    


                    //获取jsticket的执行体         


                    params.clear();         


                    params.put(          "access_token"          , access_token);         


                    params.put(          "type"          ,           "jsapi"          );         


                    String jsticket = HttpUtils.sendGet(         


                    GlobalConstants.getInterfaceUrl(          "ticketUrl"          ), params);         


                    String jsapi_ticket = JSONObject.fromObject(jsticket).getString(         


                    "ticket"          );          


                    GlobalConstants.interfaceUrlProperties         


                    .put(          "jsapi_ticket"          , jsapi_ticket);           // 获取到js-SDK的ticket并赋值保存         


                    


                    System.out.println(          "jsapi_ticket================================================"           + jsapi_ticket);         


                    System.out.println(          new           SimpleDateFormat(          "yyyy-MM-dd HH:mm:ss"          ).format(          new           Date())+          "token为=============================="          +access_token);         


                    


                    }         


                    


          }



然后我们根据【JS-SDK使用权限签名算法】对参数进行签名得到signature,这里的url必须采用前端传递到后端,因为每次的url会有所变化,如下:



package           com.dy.wechat.common;         


                    


          import           java.security.MessageDigest;         


          import           java.util.Formatter;         


          import           java.util.HashMap;         


          import           java.util.UUID;         


          import           com.cuiyongzhi.web.util.GlobalConstants;         


                    


                    


          /**         


                    * ClassName: JSSDK_Config         


                    * @Description: 用户微信前端页面的jssdk配置使用         


                    * @author jerry_hello         


                    * @date 2017年12月26日 15:27         


                    */         


          public           class           JSSDK_Config {         


                    


                    /**         


                    * @Description: 前端jssdk页面配置需要用到的配置参数         


                    * @param @return hashmap {appid,timestamp,nonceStr,signature}         


                    * @param @throws Exception            


                    * @author jerry_hello         


                    * @date 2017年12月26日 下午15:27         


                    */         


                    public           static           HashMap<String, String> jsSDK_Sign(String url)           throws           Exception {         


                    String nonce_str = create_nonce_str();         


                    String timestamp=GlobalConstants.getInterfaceUrl(          "timestamp"          );         


                    String jsapi_ticket=GlobalConstants.getInterfaceUrl(          "jsapi_ticket"          );         


                    // 注意这里参数名必须全部小写,且必须有序         


                    String  string1 =           "jsapi_ticket="           + jsapi_ticket +           "&noncestr="           + nonce_str         


                    +           "×tamp="           + timestamp  +           "&url="           + url;         


                    MessageDigest crypt = MessageDigest.getInstance(          "SHA-1"          );         


                    crypt.reset();         


                    crypt.update(string1.getBytes(          "UTF-8"          ));         


                    String signature = byteToHex(crypt.digest());         


                    HashMap<String, String> jssdk=          new           HashMap<String, String>();         


                    jssdk.put(          "appId"          , GlobalConstants.getInterfaceUrl(          "appid"          ));         


                    jssdk.put(          "timestamp"          , timestamp);         


                    jssdk.put(          "nonceStr"          , nonce_str);         


                    jssdk.put(          "signature"          , signature);         


                    return           jssdk;         


                    


                    }         


                    


                    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();         


                    }         


                    


          }



然后我们将后端签名的方法集成到Controller层,形成代码如下:



package           com.dy.wechat.controller;         


                    


          import           java.util.Map;         


          import           org.springframework.stereotype.Controller;         


          import           org.springframework.web.bind.annotation.RequestMapping;         


          import           org.springframework.web.bind.annotation.RequestParam;         


          import           com.cuiyongzhi.Message;         


          import           com.cuiyongzhi.wechat.common.JSSDK_Config;         


                    


          /**         


                    * ClassName: WeChatController         


                    * @Description: 前端用户微信配置获取         


                    * @author jerry_hello         


                    * @date 2017年12月26日 15:27         


                    */         


          @Controller         


          @RequestMapping          (          "/wechatconfig"          )         


          public           class           WeChatController {         


                    


                    /**         


                    * @Description: 前端获取微信JSSDK的配置参数         


                    * @param @param response         


                    * @param @param request         


                    * @param @param url         


                    * @param @throws Exception         


                    * @author jerry_hello         


                    * @date 2017年12月26日 15:27         


                    */         


                    @RequestMapping          (          "jssdk"          )         


                    public           Message JSSDK_config(         


                    @RequestParam          (value =           "url"          , required =           true          ) String url) {         


                    try           {         


                    System.out.println(url);         


                    Map<String, String> configMap = JSSDK_Config.jsSDK_Sign(url);         


                    return           Message.success(configMap);         


                    }           catch           (Exception e) {         


                    return           Message.error();         


                    }         


                    


                    }         


                    


          }



到这里我们后端对jssdk的签名参数的封装就基本完成了,下一步就只需要我们前端调用就可以了!

(三)页面实现JS-SDk中config的注入配置,并实现对成功和失败的处理

在第二步中我们将后端接口代码完成了,这里新建jssdkconfig.jsp,在jsp页面用ajax方式获取并进行配置,并开启debug模式,打开之后就可以看到配置是否成功的提示,简单代码如下:




<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 

 <% 

String path = request.getContextPath(); 

 %> 

 <!DOCTYPE html> 

 <html> 

 <head> 

 <script src="res/js/jquery.min.js"></script> 

 <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> 

 <script type="text/javascript"> 

    function jssdk() { 

        $.ajax({ 

            url : "http://www.xxxx.com 
        /wechatconfig/jssdk.action",         
            type : 'post', 

            dataType : 'json', 

            contentType : "application/x-www-form-urlencoded; charset=utf-8", 

            data : { 

                'url' : location.href.split('#')[0] 

            }, 

            success : function(data) { 

            
        wx.config({         
                    debug : falsess, 

                    appId : data.appId, 

                    timestamp : data.timestamp, 

                    nonceStr :  data.nonceStr, 

                    signature : data.signature, 

                    jsApiList : ['getLocation'] 

                }); 

                //wx.config 验证成功后执行wx.ready 

                wx.ready(function(){ 

                
         wx.getLocation({         
                         success: function (res) { 

                            alert("经纬度: latitude="+res.latitude+" longitude="+res.longitude) 

                         }, 

                         fail: function(error) { 

                        
                   
                         } 

                     }); 

                }); 

                //wx.config 验证失败后执行wx.error 

                wx.error(function(){ 

                

                }); 

            } 

        }); 

    } 

  

   /*  function isWeiXin5() { 

        var ua = window.navigator.userAgent.toLowerCase(); 

        var reg = /MicroMessenger\/[5-9]/i; 

        return reg.test(ua); 

    } */ 

  

    window.onload = function() { 

        jssdk(); 

    }; 

    

</script> 

 </head> 

 <body> 



 </body> 

 </html>



最后我们运行代码,查看运行结果:


如果提示如上显示,那么到这里微信jssdk的配置就基本完成了