1. 程式人生 > >JAVA版 微信企業號開發 個人總結(微信網頁授權例子,微信企業號精準定位,誤差5-10米)

JAVA版 微信企業號開發 個人總結(微信網頁授權例子,微信企業號精準定位,誤差5-10米)

總路線

主要內容:案例微信網頁授權,企業號精準定位(誤差5-10米)
一、 access_token獲取
二、 獲取js-sdk的許可權,票據jsapi_ticket
三、js-sdk的signature
四、js-sdk前臺配置,獲取精準的經緯度
五、額外附加 java定時器

一、 access_token獲取

原理:獲取公眾號的corpid和corpsecret,對https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=你的corpid&corpsecret=你的corpsecret進行get請求,返回獲取access_token,注意access_token的有效時間為7200秒,而請求access_token的次數是有限的,需要用定時器定時獲取(後續講述定時器,也可以用其他方法代替)

    /**
     * http GET請求封裝
     * 
     * @param url
     * @return
     */
    public static JSONObject doGet(String url) {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet get = new HttpGet(url);
        JSONObject obj = new JSONObject();
        try {
            HttpResponse response = httpClient.execute(get);
            HttpEntity entity = response.getEntity();
            if
(entity != null) { String result = EntityUtils.toString(entity, "utf-8"); obj = JSONObject.parseObject(result); } } catch (Exception e) { e.printStackTrace(); } return obj; } /** * 獲取accesstoken,儲存access_token * * @return
*/
public static String getToken() { String access_token = ""; String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=你的corpid&corpsecret=你的corpsecret"; JSONObject obj = doGet(url); if (obj != null) { access_token = obj.getString("access_token"); //這裡進行資料儲存accesstoken或者全域性快取accesstoken //--------- //---------- } return access_token; }

二、 獲取js-sdk的許可權,票據jsapi_ticket

原理,通過access_token來換取jsapi_ticket

    /**
     * 獲取js-sdk的許可權,票據ticket
     * 
     * @return
     */
    public static String ticket() {
        String access_token = getToken();// 建議從資料庫中獲取,或者全域性快取中獲取,這只是個本地的例子
        JSONObject obj1 = doGet("https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + access_token);
        if (obj1 != null) {
            String jsapi_ticket = obj1.getString("ticket");// 全域性快取jsapi_ticket
            //這裡進行資料儲存jsapi_ticket或者全域性快取jsapi_ticket
            //---------
            //----------
            return jsapi_ticket;
        }
        return "fail";
    }

三、js-sdk的signature

(後臺)原理,java後臺進行signature(主要進行sha1加密)
後臺進行sha1加密,用json格式返回前端,然前端進行處理

/**
     * 按照固定的排序方式進行sha1加密
     * 
     * @param url
     *            傳遞進來的url引數
     * @return
     */
    public static JSONObject signature(String url) {
        JSONObject obj = new JSONObject();
        SimpleDateFormat sdFormat = new SimpleDateFormat("yyyyMMddhh"); // 時間戳格式化,必須取10位
        String timestamp = sdFormat.format(new Date());// 當前時間戳
        String noncestr = getRandom(9);// 9位隨機數
        String signature = "jsapi_ticket=" + WxUtil.ticket();// 獲取資料
        signature += "&" + "noncestr=" + noncestr;
        signature += "&" + "timestamp=" + timestamp;
        signature += "&" + "url=" + url;
        signature = SHA1(signature);
        obj.put("timestamp", timestamp);
        obj.put("signature", signature);
        obj.put("noncestr", noncestr);
        System.out.println("\n" + obj);
        return obj;
    }

    /**
     * @description: SHA、SHA1加密方法 @parameter: str:待加密字串 @return: 加密串
     **/
    public static String SHA1(String str) {
        try {
            MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1"); // 如果是SHA加密只需要將"SHA-1"改成"SHA"即可
            digest.update(str.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexStr = new StringBuffer();
            // 位元組陣列轉換為 十六進位制 數
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexStr.append(0);
                }
                hexStr.append(shaHex);
            }
            return hexStr.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成一定位數的隨機數
     * 
     * @param length
     * @return
     */
    public static String getRandom(int length) {
        String allChar = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuffer sb = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++)
            sb.append(allChar.charAt(random.nextInt(allChar.length())));

        return sb.toString();
    }

四、js-sdk前臺配置,獲取精準的經緯度

前臺,用js進行微信js-sdk的配置
原理:ajax獲取wx.config所需要的配置資訊,配置成功後進行使用微信自帶的定位功能獲取經緯度,然後把獲得的經緯度通過百度地圖的座標轉換api的介面,從而獲得在百度地圖上獲得比較精準的地理位置
執行順序
wx.config>wx.ready
注意:js中的程式碼,注意必須先引入如下JS檔案,(支援https):http://res.wx.qq.com/open/js/jweixin-1.1.0.js 和jq檔案

var flag = false;
var long = '';
var lat = '';
wx.ready(function() {
                getLocation();
            });

            function signature() {
                $.ajax({
                    url: '9',
                    data: { 'url': "當前頁面url,不包括url#後面的"},
                    type: "get",
                    dataType: 'json',
                    success: function(data) {
                    // 可以參考微信企業號開發平臺的js-sdk文件
                        wx.config({
                            appId: '你的cropid', // 必填,公眾號的唯一標識
                            timestamp: data.timestamp, // 必填,生成簽名的時間戳
                            nonceStr: data.noncestr, // 必填,生成簽名的隨機串
                            signature: data.signature, //必填,簽名
                            jsApiList: ['openLocation', 'getLocation', 'chooseImage', 'uploadImage'] // 必填,需要使用的JS介面列表
                        });
                        flag = true;
                    },
                    error: function(data) {
                        alert('fail');
                    }
                });
            }
            //使用微信自帶的定位
            function getLocation() {
                if(flag) {

                    wx.getLocation({
                        type: 'wgs84', // 預設為wgs84的gps座標,如果要返回直接給openLocation用的火星座標,可傳入'gcj02'
                        success: function(res) {
                            var latitude = res.latitude; // 緯度,浮點數,範圍為90 ~ -90
                            var longitude = res.longitude; // 經度,浮點數,範圍為180 ~ -180。
                            var speed = res.speed; // 速度,以米/每秒計
                            var accuracy = res.accuracy; // 位置精度
                            changeLocation(longitude, latitude);
                        }
                    });
                } else {
                    alert("flag not true");
                    signature();
                    getLocation();
                }

            }
            //座標轉換API,Web服務API(百度api)
            function changeLocation(Long, Lat) {
                $.ajax({
                    url: "http://api.map.baidu.com/geoconv/v1/?coords=" + Long + "," + Lat + "&from=1&to=5&ak=你的金鑰",
                    type: "get",
                    dataType: 'jsonp',
                    success: function(data) {
                        long = data.result[0].x;
                        lat = data.result[0].y;
                        //chooseImg();
                    },
                    error: function(data) {
                        alert('fail');
                    }
                });
            }

五、額外附加 定時器

配置xml檔案
使用註解進行定時排程,注意cron是時間

@Component
public class TimeTask {
    /**
     * 
     * 秒 0-59 , - * / 
     * 分 0-59 , - * / 
     * 小時 0-23 , - * / 
     * 日期 1-31 , - * ? / L W C 
     * 月份 1-12 或者 JAN-DEC , - * / 
     * 星期 1-7 或者 SUN-SAT , - * ? / L C # 
     * 年(可選)留空, 1970-2099 , - * /
     * cron = "0 0 0/1 * * ?"相當於每小時進行一次操作
     * @throws Exception
     */

    @Scheduled(cron = "0 0 0/1 * * ?")
    public void task() throws Exception {
        System.out.println("---------------------task start--------------------");
        //呼叫你的獲取access_token的方法,呼叫你的獲取jsapi_ticket的方法

        System.out.println("---------------------task end--------------------");
    }
}

相關xml的配置
這裡寫圖片描述

相關程式碼:

<beans xmlns:task="http://www.springframework.org/schema/task"

 xsi:schemaLocation=http://www.springframework.org/schema/task
      http://www.springframework.org/schema/task/spring-task-3.2.xsd">

   <!-- 設定定時任務 -->
    <task:annotation-driven/>
    </beans>