-
申请一个测试账号 微信公众测试号
-
配置安全域名
-
花生壳内网击穿
-
在html页面引入微信的js
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
其次是js中代码
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '你自己的appId', // 必填,公众号的唯一标识,这里你要使用自己的,我这是测试号
timestamp:'${timestamp}', // 必填,生成签名的时间戳
nonceStr: '${nonceStr}', // 必填,生成签名的随机串
signature: '${signature}',// 必填,签名
jsApiList: ['openLocation'] // 必填,需要使用的JS接口列表
});
wx.checkJsApi({
jsApiList: ['getLocation'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function(res) {
if (res.checkResult.getLocation == false) {
alert('你的微信版本太低,不支持微信JS接口,请升级到最新的微信版本!');
return;
}
}
});
wx.ready(function(){
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var accuracy = res.accuracy; // 位置精度
console.log(latitude);
console.log(longitude);
alert(latitude);
alert(longitude);
},
cancel: function (res) {
alert('用户拒绝授权获取地理位置');
}
});
})
- 然后是java代码
这里提供一个工具类WeChatCommonUtil
注意CacheUtil
是我们公司自己的工具类,需要配置ehcache.xml
缓存,稍嫌麻烦,此处代码就不放了,读者可以用存储数据库的方式,将token和ticket放入数据库中,另外需要注意必须要存储,不能每次都从微信服务器获取,默认每两小时刷新一次,如果向微信请求次数过多,微信会给你停掉此功能貌似
package com.xxxx;
import com.alibaba.fastjson.JSON;
import com.xxxxx.CacheUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import java.util.Map;
import java.util.UUID;
/**
* 获取微信签名参数工具类
*/
@Slf4j
public class WeChatCommonUtil {
//这里注意,这些配置参数可以统一放到配置文件中,然后此处用@Value引入
private static String appId = "你自己的appId";
private static String secret = "你自己的secret";
//获取token的url
private static String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
//获取ticket的地址
private static String ticketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi";
//http请求可以用hutool工具包简化,此处测试可行,不过代码我懒得改了
public static void main(String[] args) {
String result3= HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appsecret);
System.out.println(result3);
JSONObject jsonObject = JSONUtil.parseObj(result3);
System.out.println(jsonObject.get("access_token"));
System.out.println(jsonObject.get("expires_in"));
//https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
String result4= HttpUtil.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+jsonObject.get("access_token")+"&type=jsapi");
JSONObject jsonObject1 = JSONUtil.parseObj(result4);
System.out.println(jsonObject1.get("ticket"));
//token 36_1YdBkJsZlOGfZzhTHaGUlyUQ1oVdqGGVizGA5QgpEG-OXFDdt0jtuW6sbBiFm62WDqYUlEHulqXyyWG-gY2sR8I9S9RV8cmkDKSIq0ttlM-wABX-OUA5gZTFtuR3qwW--rlseFGB93pnQSbDRZMiABALTG
//ticket O3SMpm8bG7kJnF36aXbe85x8Jw1a1tXfXeEGdSC4VuL-iDdE7jcbYkchwmasGcF3J01gBDszmjhS-_TUaLaiog
}
public static String getAccessToken() {
HttpClient client = HttpClients.createDefault();
HttpGet get = new HttpGet(MessageFormat.format(accessTokenUrl,appId,secret));
try {
String accessToken = (String) CacheUtil.get("wxCache", "accessToken");;
if (StringUtils.isBlank(accessToken) || StringUtils.isEmpty(accessToken)) {
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");
System.out.println(result);
Map<String, Object> accessTokenMap = JSON.parseObject(result);
accessToken = (String)accessTokenMap.get("access_token");
CacheUtil.put("wxCache", "accessToken", accessToken);
}
return accessToken;
} catch (ClientProtocolException e) {
log.error(e.getMessage());
} catch (IOException e) {
log.error(e.getMessage());
}
return null;
}
public static String getTicket(String accessToken) {
HttpClient client = HttpClients.createDefault();
HttpGet get = new HttpGet(MessageFormat.format(ticketUrl,accessToken));
try {
String ticket = (String) CacheUtil.get("wxCache", "jsapi_ticket");
if (StringUtils.isBlank(ticket) || StringUtils.isEmpty(ticket)) {
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");
System.out.println(result);
Map<String, Object> jsApiTicketMap = JSON.parseObject(result);
ticket = (String)jsApiTicketMap.get("ticket");
CacheUtil.put("wxCache", "jsapi_ticket", ticket);
}
return ticket;
} catch (ClientProtocolException e) {
log.error(e.getMessage());
} catch (IOException e) {
log.error(e.getMessage());
}
return null;
}
public static String getNoncestr(){
String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
return noncestr;
}
public static String getTimestamp(){
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
return timestamp;
}
public static String getUrl(String url){
//String url="http://xqgz.damiao.vip:18090/applet/appletInit";
return url;
}
/**
* @Param [signature, timestamp, ticket, echostr]
* @Return java.lang.String
* @Description: 对所有待签名参数按照字段名的ASCII 码从小到大排序
*/
public static String sort(String url, String timestamp, String ticket, String noncestr) {
return "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url;
}
/**
* @Param [str]
* @Return java.lang.String
* @Description: 将字符串进行sha1加密
*/
public static String sha1(String str){
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(str.getBytes());
byte messageDigest[] = digest.digest();
// 创建 16进制字符串
StringBuffer hexString = new StringBuffer();
// 字节数组转换为 十六进制 数
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
}
controller层
@Controller
@RequestMapping("/xxx")
public class XxxController {
public Map<String,String> test(){
//1.获取access_token 需要定时刷
String accessToken = WeChatCommonUtil.getAccessToken();
if (accessToken == null){
System.out.println("失败");
return null;
}
//2.通过access_token获得ticket 需要定时刷新
String ticket = WeChatCommonUtil.getTicket(accessToken);
if (ticket == null){
System.out.println("失败");
return null;
}
//3.时间戳和随机字符串
String noncestr = WeChatCommonUtil.getNoncestr();
String timestamp = WeChatCommonUtil.getTimestamp();
//4、获取url
// String url = WeChatCommonUtil.getUrl(pathUrl);
String url = WeChatCommonUtil.getUrl("http://javaweb.55555.io/xxx/toMine");
//5、将参数排序并拼接字符串
String sortString = WeChatCommonUtil.sort(url, timestamp, ticket, noncestr);
//6、将字符串进行sha1加密
String signature = WeChatCommonUtil.sha1(sortString);
Map<String,String> map = Maps.newHashMap();
map.put("appId",appId);
map.put("timestamp",timestamp);
map.put("nonceStr",noncestr);
map.put("signature",signature);
return map;
}
@RequestMapping("/toMine")
public String toMine(HttpServletRequest request) {
Map<String,String> map = test();
request.setAttribute("appId",appId);
request.setAttribute("timestamp",map.get("timestamp"));
request.setAttribute("nonceStr",map.get("nonceStr"));
request.setAttribute("signature",map.get("signature"));
return PREFIX + "/mine.html";
}
}
以上经测试可以正常获取经纬度
测试时建议用微信开发者工具