Java微信公眾平臺之獲取地理位置
本部分需要用到微信的JS-SDK,微信JS-SDK是微信公眾平臺面向網(wǎng)頁開發(fā)者提供的基于微信內的網(wǎng)頁開發(fā)工具包。
通過使用微信JS-SDK,網(wǎng)頁開發(fā)者可借助微信高效地使用拍照、選圖、語音、位置等手機系統(tǒng)的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信用戶提供更優(yōu)質的網(wǎng)頁體驗。
一、JS-SDK引入
1.先登錄微信公眾平臺進入“公眾號設置”的“功能設置”里填寫“JS接口安全域名”,和網(wǎng)頁授權一樣只是個域名。
2.在需要調用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接口注入權限驗證配置
wx.config({
debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
appId: '', // 必填,公眾號的唯一標識
timestamp: , // 必填,生成簽名的時間戳
nonceStr: '', // 必填,生成簽名的隨機串
signature: '',// 必填,簽名
jsApiList: [] // 必填,需要使用的JS接口列表
});
首先生成這個signature之前需要獲取到一個臨時票據(jù)jsapi_ticket,jsapi_ticket是公眾號用于調用微信JS接口的臨時票據(jù)。正常情況下,jsapi_ticket的有效期為7200秒,通過access_token來獲取。由于獲取jsapi_ticket的api調用次數(shù)非常有限,頻繁刷新jsapi_ticket會導致api調用受限,影響自身業(yè)務,同樣也需要個中控服務器控制刷新。
1、獲取臨時票據(jù)
封裝返回結果
package com.phil.wechatauth.model.resp;
import com.phil.common.result.ResultState;
/**
* jsapi_ticket是公眾號用于調用微信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 調用微信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(隨機字符串), 有效的jsapi_ticket, timestamp(時間戳), url(當前網(wǎng)頁的URL,不包含#及其后面部分) 。對所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1。這里需要注意的是所有參數(shù)名均為小寫字符。對string1作sha1加密,字段名和字段值都采用原始值,不進行URL 轉義。
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接口處理成功驗證
以上執(zhí)行完成,進入的完整的頁面
<%@ 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, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
appId: '${jsWechatConfig.appId}', // 必填,公眾號的唯一標識
timestamp: '${jsWechatConfig.timestamp}' , // 必填,生成簽名的時間戳
nonceStr: '${jsWechatConfig.noncestr}', // 必填,生成簽名的隨機串
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信息驗證后會執(zhí)行ready方法,所有接口調用都必須在config接口獲得結果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數(shù)中調用來確保正確執(zhí)行。對于用戶觸發(fā)時才調用的接口,則可以直接調用,不需要放在ready函數(shù)中。
wx.getLocation({
success : function(res) {
latitude = res.latitude; // 緯度,浮點數(shù),范圍為90 ~ -90
longitude = res.longitude; // 經(jīng)度,浮點數(shù),范圍為180 ~ -180。
speed = res.speed; // 速度,以米/每秒計
accuracy = res.accuracy; // 位置精度
alert(latitude);
alert(accuracy);
},
cancel : function(res) {
alert('未能獲取地理位置');
}
});
});
wx.error(function(res){
// config信息驗證失敗會執(zhí)行error函數(shù),如簽名過期導致驗證失敗,具體錯誤信息可以打開config的debug模式查看,也可以在返回的res參數(shù)中查看,對于SPA可以在這里更新簽名。
alert("驗證出錯");
});
</script>
</html>
可以通過微信官方提供的微信web開發(fā)者工具調試。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Spring動態(tài)添加定時任務的實現(xiàn)思路
這篇文章主要介紹了Spring動態(tài)添加定時任務的實現(xiàn)思路,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-07-07
Java實現(xiàn)單鏈表SingleLinkedList增刪改查及反轉 逆序等
單鏈表是鏈表的其中一種基本結構。一個最簡單的結點結構如圖所示,它是構成單鏈表的基本結點結構。在結點中數(shù)據(jù)域用來存儲數(shù)據(jù)元素,指針域用于指向下一個具有相同結構的結點。 因為只有一個指針結點,稱為單鏈表2021-10-10
@SpringBootConfiguration重復加載報錯問題解決
@SpringBootApplication?注解的?exclude?屬性用于排除特定的自動配置類,而不是用于排除主配置類本身,因此,不能通過?exclude?屬性來排除主配置類的加載,這篇文章主要介紹了@SpringBootConfiguration重復加載報錯,需要的朋友可以參考下2024-08-08
Java Synchronize下的volatile關鍵字詳解
這篇文章主要介紹了Java Synchronize下的volatile關鍵字詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03

