Java微信公眾平臺之獲取地理位置
本部分需要用到微信的JS-SDK,微信JS-SDK是微信公眾平臺面向網(wǎng)頁開發(fā)者提供的基于微信內(nèi)的網(wǎng)頁開發(fā)工具包。
通過使用微信JS-SDK,網(wǎng)頁開發(fā)者可借助微信高效地使用拍照、選圖、語音、位置等手機(jī)系統(tǒng)的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信用戶提供更優(yōu)質(zhì)的網(wǎng)頁體驗(yàn)。
一、JS-SDK引入
1.先登錄微信公眾平臺進(jìn)入“公眾號設(shè)置”的“功能設(shè)置”里填寫“JS接口安全域名”,和網(wǎng)頁授權(quán)一樣只是個域名。
2.在需要調(diào)用JS接口的頁面引入如下JS文件之一
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
二、通過config接口注入權(quán)限驗(yàn)證配置
wx.config({
debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
appId: '', // 必填,公眾號的唯一標(biāo)識
timestamp: , // 必填,生成簽名的時間戳
nonceStr: '', // 必填,生成簽名的隨機(jī)串
signature: '',// 必填,簽名
jsApiList: [] // 必填,需要使用的JS接口列表
});
首先生成這個signature之前需要獲取到一個臨時票據(jù)jsapi_ticket,jsapi_ticket是公眾號用于調(diào)用微信JS接口的臨時票據(jù)。正常情況下,jsapi_ticket的有效期為7200秒,通過access_token來獲取。由于獲取jsapi_ticket的api調(diào)用次數(shù)非常有限,頻繁刷新jsapi_ticket會導(dǎo)致api調(diào)用受限,影響自身業(yè)務(wù),同樣也需要個中控服務(wù)器控制刷新。
1、獲取臨時票據(jù)
封裝返回結(jié)果
package com.phil.wechatauth.model.resp;
import com.phil.common.result.ResultState;
/**
* jsapi_ticket是公眾號用于調(diào)用微信JS接口的臨時票據(jù)
* @author phil
* @date 2017年8月21日
*
*/
public class JsapiTicket extends ResultState {
/**
*
*/
private static final long serialVersionUID = -357009110782376503L;
private String ticket; //jsapi_ticket
private String expires_in;
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public String getExpires_in() {
return expires_in;
}
public void setExpires_in(String expires_in) {
this.expires_in = expires_in;
}
}
獲取方法
/**
* 獲取jsapi_ticket 調(diào)用微信JS接口的臨時票據(jù)
* @return
*/
public String getTicket(String accessToken) {
JsapiTicket jsapiTicket = null;
Map<String,String> params = new TreeMap<String,String>();
params.put("access_token",accessToken);
params.put("type", "jsapi");
String result = HttpReqUtil.HttpDefaultExecute(HttpReqUtil.GET_METHOD, WechatConfig.GET_TICKET_URL, params,"");
if(StringUtils.isNotBlank(result)){
jsapiTicket = JsonUtil.fromJson(result, JsapiTicket.class);
}
if(jsapiTicket.getErrcode()==0){
return jsapiTicket.getTicket();
}
return null;
}
2、生成簽名并返回參數(shù)
signature生成規(guī)則如下:參與簽名的字段包括noncestr(隨機(jī)字符串), 有效的jsapi_ticket, timestamp(時間戳), url(當(dāng)前網(wǎng)頁的URL,不包含#及其后面部分) 。對所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1。這里需要注意的是所有參數(shù)名均為小寫字符。對string1作sha1加密,字段名和字段值都采用原始值,不進(jìn)行URL 轉(zhuǎn)義。
string1示例如下
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
這里有個坑,頁面是nonceStr,但是簽名的字段是noncestr,注意大小寫
簡單封裝下JS-SDK config配置信息
package com.phil.wechatauth.model.resp;
/**
* JS-SDK的頁面配置信息
* @author phil
* @date 2017年8月22日
*
*/
public class JsWechatConfig {
private String appId;
private long timestamp;
private String noncestr;
private String signature;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getNoncestr() {
return noncestr;
}
public void setNoncestr(String noncestr) {
this.noncestr = noncestr;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
}
添加配置信息到頁面
/**
*
*/
package com.phil.wechatauth.controller;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.phil.common.config.SystemConfig;
import com.phil.common.config.WechatConfig;
import com.phil.common.util.DateTimeUtil;
import com.phil.common.util.PayUtil;
import com.phil.common.util.SignatureUtil;
import com.phil.wechatauth.model.resp.JsWechatConfig;
import com.phil.wechatauth.service.WechatAuthService;
/**
* JS-SDK
* @author phil
* @date 2017年8月21日
*
*/
@Controller
@RequestMapping("/auth")
public class WechatAuthController {
@Autowired
private WechatAuthService wechatAuthService;
/**
* 獲取地理位置
* @param request
* @return
* @throws Exception
*/
@RequestMapping("/getLocation")
public String getLocation(HttpServletRequest request) throws Exception{
JsWechatConfig jsWechatConfig = new JsWechatConfig();
jsWechatConfig.setAppId(WechatConfig.APP_ID);
jsWechatConfig.setTimestamp(DateTimeUtil.currentTime());
jsWechatConfig.setNoncestr(PayUtil.createNonceStr());
SortedMap<Object,Object> map = new TreeMap<Object,Object>();
map.put("jsapi_ticket", wechatAuthService.getTicket(wechatAuthService.findlastestToken()));
map.put("noncestr", jsWechatConfig.getNoncestr());
map.put("timestamp", jsWechatConfig.getTimestamp());
map.put("url", request.getRequestURL().toString());
String signature = SignatureUtil.createSha1Sign(map, null, SystemConfig.CHARACTER_ENCODING);
jsWechatConfig.setSignature(signature);
request.setAttribute("jsWechatConfig", jsWechatConfig);
return "wechatauth/getLocation";
}
}
簽名方法
/**
* 通過Map<SortedMap,Object>中的所有元素參與簽名
*
* @param map 待參與簽名的map集合
* @params apikey apikey中 如果為空則不參與簽名,如果不為空則參與簽名
* @return
*/
public static String createSha1Sign(SortedMap<Object, Object> map, String apiKey, String characterEncoding) {
String result = notSignParams(map, apiKey);
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
byte[] digest = md.digest(result.getBytes());
result = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return result;
}
其他的簽名方法
三、通過ready接口處理成功驗(yàn)證
以上執(zhí)行完成,進(jìn)入的完整的頁面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>獲取地理位置</title>
<!-- 微信 js-sdk -->
<script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<link rel="stylesheet" >
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<br>
<div class="container">
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">地址:</label>
<div class="col-sm-10" id="item-ifo">
<input type="text" value="" class="form-control"
name="location.address" id="address" placeholder="正在獲取地理位置" tabindex="1" autocomplete="off" />
<div class="i-name ico" id="i-name"></div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
wx.config({
debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
appId: '${jsWechatConfig.appId}', // 必填,公眾號的唯一標(biāo)識
timestamp: '${jsWechatConfig.timestamp}' , // 必填,生成簽名的時間戳
nonceStr: '${jsWechatConfig.noncestr}', // 必填,生成簽名的隨機(jī)串
signature: '${jsWechatConfig.signature}',// 必填,簽名,見附錄1
jsApiList: [ 'checkJsApi', 'openLocation', 'getLocation'] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2
});
wx.checkJsApi({
jsApiList: ['getLocation'], // 需要檢測的JS接口列表,所有JS接口列表見附錄2,
success: function(res) {
if (res.checkResult.getLocation == false) {
alert('你的微信版本太低,不支持微信JS接口,請升級到最新的微信版本!');
return;
}
}
});
var latitude;
var longitude;
var speed;
var accuracy;
wx.ready(function(){
// config信息驗(yàn)證后會執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調(diào)用相關(guān)接口,則須把相關(guān)接口放在ready函數(shù)中調(diào)用來確保正確執(zhí)行。對于用戶觸發(fā)時才調(diào)用的接口,則可以直接調(diào)用,不需要放在ready函數(shù)中。
wx.getLocation({
success : function(res) {
latitude = res.latitude; // 緯度,浮點(diǎn)數(shù),范圍為90 ~ -90
longitude = res.longitude; // 經(jīng)度,浮點(diǎn)數(shù),范圍為180 ~ -180。
speed = res.speed; // 速度,以米/每秒計
accuracy = res.accuracy; // 位置精度
alert(latitude);
alert(accuracy);
},
cancel : function(res) {
alert('未能獲取地理位置');
}
});
});
wx.error(function(res){
// config信息驗(yàn)證失敗會執(zhí)行error函數(shù),如簽名過期導(dǎo)致驗(yàn)證失敗,具體錯誤信息可以打開config的debug模式查看,也可以在返回的res參數(shù)中查看,對于SPA可以在這里更新簽名。
alert("驗(yàn)證出錯");
});
</script>
</html>
可以通過微信官方提供的微信web開發(fā)者工具調(diào)試。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring動態(tài)添加定時任務(wù)的實(shí)現(xiàn)思路
這篇文章主要介紹了Spring動態(tài)添加定時任務(wù)的實(shí)現(xiàn)思路,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-07-07
Java實(shí)現(xiàn)單鏈表SingleLinkedList增刪改查及反轉(zhuǎn) 逆序等
單鏈表是鏈表的其中一種基本結(jié)構(gòu)。一個最簡單的結(jié)點(diǎn)結(jié)構(gòu)如圖所示,它是構(gòu)成單鏈表的基本結(jié)點(diǎn)結(jié)構(gòu)。在結(jié)點(diǎn)中數(shù)據(jù)域用來存儲數(shù)據(jù)元素,指針域用于指向下一個具有相同結(jié)構(gòu)的結(jié)點(diǎn)。 因?yàn)橹挥幸粋€指針結(jié)點(diǎn),稱為單鏈表2021-10-10
SpringBoot?上傳文件判空以及格式檢驗(yàn)流程
這篇文章主要介紹了SpringBoot?上傳文件判空以及格式檢驗(yàn)流程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
@SpringBootConfiguration重復(fù)加載報錯問題解決
@SpringBootApplication?注解的?exclude?屬性用于排除特定的自動配置類,而不是用于排除主配置類本身,因此,不能通過?exclude?屬性來排除主配置類的加載,這篇文章主要介紹了@SpringBootConfiguration重復(fù)加載報錯,需要的朋友可以參考下2024-08-08
Java Synchronize下的volatile關(guān)鍵字詳解
這篇文章主要介紹了Java Synchronize下的volatile關(guān)鍵字詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03
SpringBoot靜態(tài)資源的訪問方法詳細(xì)介紹
最近在做SpringBoot項(xiàng)目的時候遇到了“白頁”問題,通過查資料對SpringBoot訪問靜態(tài)資源做了總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-09-09
Spring框架實(shí)現(xiàn)滑動驗(yàn)證碼功能的代碼示例
之前項(xiàng)目需要在驗(yàn)證碼模塊,增加滑動驗(yàn)證碼,用來給手機(jī)端使用的,大概看了下,主要方法就是將圖片切割,然后記住偏移量,進(jìn)行滑動,所以本文給大家介紹了Spring框架實(shí)現(xiàn)滑動驗(yàn)證碼功能的方法示例,需要的朋友可以參考下2024-07-07

