//前台jquery相关代码
//‘url’: encodeURIComponent(location.href.split(’#’)[0])
var url = window.location.href;
$.ajax({
url: “/h5/getWxToken.do”, //获取微信token信息
type: “post”,
data: {
‘url’: url
},
dataType: “json”,
success: function (data) {
// 生成签名后,开始使用微信的 wx.config 。其中jsApiList就是我们要用的API的列表,因为只需要取经纬度,所以用getLocation就可以了
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: data.appId, // 必填,公众号的唯一标识
timestamp: data.timestamp, // 必填,生成签名的时间戳
nonceStr: data.nonceStr, // 必填,生成签名的随机串
signature: data.signature, // 必填,签名,见附录1
jsApiList: [
‘getLocation’
]
});
wx.error(function (res) {
//alert(“失败:”+res.msg);
});
// wx.config 检测无误后,会进入到 ready 方法 。 注意type参数。微信多数的坐标体系都为gcj02
wx.ready(function () {
wx.getLocation({
type: “gcj02”,// 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入’gcj02’
success: function (res) {
//获取到的经纬度
$("#latitude").val(res.latitude);
$("#longitude").val(res.longitude);
},
fail: function(err) {
alert(“获取定位位置信息失败!”)
},
cancel: function (res) {
alert(‘用户拒绝授权获取地理位置’);
}
});
});
}
});
后台java相关代码
package com.jrfmail.useroa.h5Action;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeewx.api.core.common.MyX509TrustManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jrfmail.core.web.WebUtils;
import com.jrfmail.wx.api.HttpMethod;
import com.jrfmail.wx.model.AccessToken;
import com.jrfmail.wx.model.JSTicket;
import com.jrfmail.wx.model.WxSign;
import com.jrfmail.wx.service.WxApiService;
public class wx {
@Autowired
private WxApiService wxApiService;
// 凭证获取(GET) token 接口
private static final String TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
// 获取token接口
public static String getTokenUrl(String appId, String appSecret) {
return String.format(TOKEN, appId, appSecret);
}
//微信公众号相关信息
private final String WX_APPID = "";
private final String WX_APPSECRET = "";
/**
* 获取微信分享token
* @param request
* @param response
* @param url 获取经纬度信息的页面链接
* @return
*/
@RequestMapping("/getWxToken.do")
@ResponseBody
public String getWxToken(HttpServletRequest request,HttpServletResponse response,String url){
JSONObject data = new JSONObject();
try {
AccessToken accessToken = getAccessTokenApi(WX_APPID, WX_APPSECRET);
if(accessToken!=null) {
JSTicket jsTicket = wxApiService.getJSTicket(WX_APPID, accessToken.getAccessToken());
if(jsTicket!=null) {
WxSign sign = new WxSign(WX_APPID, jsTicket.getTicket(), url);
data = JSON.parseObject(JSON.toJSONString(sign));
data.put("timestamp", sign.getTimestamp());
data.put("nonceStr", sign.getNonceStr());
data.put("signature", sign.getSignature());
data.put("appId", sign.getAppId());
data.put("code", "200");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return data.toString();
}
private AccessToken getAccessTokenApi(String appId, String appSecret) {
AccessToken token = null;
String tockenUrl = getTokenUrl(appId, appSecret);
JSONObject jsonObject = httpsRequest(tockenUrl, HttpMethod.GET, null);
if (null != jsonObject) {
if (jsonObject.containsKey("errcode")) {
int errorCode = jsonObject.getInteger("errcode");
String errorMsg = jsonObject.getString("errmsg");
if (errorCode == 0) {
// 存在 且为0 微信18年后模式
token = new AccessToken(jsonObject.getString("access_token"), jsonObject.getInteger("expires_in"));
} else {
System.out.println("获取token失败 errcode:{} errmsg:{}"+errorMsg+errorMsg);
}
} else {
//不存在时 微信18年以前模式
token = new AccessToken(jsonObject.getString("access_token"), jsonObject.getInteger("expires_in"));
}
}
return token;
}
/**
* @Title: httpsRequest
* @Description: 发送https请求
* @date 2016年9月8日 下午1:44:49
* @param requestUrl 请求地址
* @param requestMethod 请求方法
* @param outputStr
* @return
*/
public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
try {
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL");//jdk7 默认 使用 TLS1模式 jdk8下默认 TLSv1.2模式 需求强制转换
sslContext.init(null, tm, new java.security.SecureRandom());
SSLSocketFactory ssf = sslContext.getSocketFactory();
//outSSLSocket(ssf);
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestMethod(requestMethod);
if (null != outputStr) {
OutputStream outputStream = conn.getOutputStream();
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
InputStream inputStream = conn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
conn.disconnect();
jsonObject = JSON.parseObject(buffer.toString());
} catch (ConnectException ce) {
ce.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return jsonObject;
}
}
package com.jrfmail.wx.model;
import java.io.Serializable;
import com.jrfmail.wx.error.ErrCode;
// 微信AccessToken
public class AccessToken implements Serializable{
/**
*
/
private static final long serialVersionUID = -2394373697219125313L;
/* 接口访问凭证 /
private String accessToken;
/* 凭证有效期,单位:秒 /
private int expiresIn;
/* 创建时间,单位:秒 ,用于判断是否过期 /
private long createTime;
/* 错误编码 /
private Integer errcode;
/* 错误消息 */
private String errmsg;
public AccessToken() {
this.createTime = System.currentTimeMillis()/1000;
}
public AccessToken(String accessToken, int expiresIn) {
this.accessToken = accessToken;
this.expiresIn = expiresIn;
this.createTime = System.currentTimeMillis()/1000;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
public Integer getErrcode() {
return errcode;
}
public void setErrcode(Integer errcode) {
this.errcode = errcode;
this.errmsg = ErrCode.errMsg(errcode);
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
}
/**
*
*/
package com.jrfmail.wx.model;
import java.io.Serializable;
import com.jrfmail.wx.error.ErrCode;
/**
-
接口凭证
*/
public class JSTicket implements Serializable{
/**
*
*/
private static final long serialVersionUID = 6576478587021591553L;
private String ticket;// 接口访问凭证
private int expiresIn;// 凭证有效期,单位:秒
private long createTime;//创建时间,单位:秒 ,用于判断是否过期
private Integer errcode;//错误编码
private String errmsg;//错误消息
public JSTicket(){
this.createTime = System.currentTimeMillis()/1000;
}
public JSTicket(String ticket,int expiresIn){
this.ticket = ticket;
this.expiresIn = expiresIn;
this.createTime = System.currentTimeMillis()/1000;
}
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
public Integer getErrcode() {
return errcode;
}
public void setErrcode(Integer errcode) {
this.errcode = errcode;
this.errmsg = ErrCode.errMsg(errcode);
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
}
/**
*
*/
package com.jrfmail.wx.model;
import java.util.Map;
import com.jrfmail.wx.util.SignUtil;
/**
- 信息签名
*/
public class WxSign {
private String appId;
private String timestamp;
private String nonceStr;
private String signature;
public WxSign(){
}
/**
* @param appId
* @param jsTicket
* @param url 当前访问页面的URL
*/
public WxSign(String appId,String jsTicket,String url){
Map<String, String> signMap = SignUtil.sign(jsTicket, url);
this.appId = appId;
this.nonceStr = signMap.get("nonceStr");
this.timestamp = signMap.get("timestamp");
this.signature = signMap.get("signature");
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String 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.jrfmail.wx.util;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.UUID;
/**
- 微信签名工具类
*/
public class SignUtil {
/**
* @param signature 微信加密签名
* @param timestamp tocken
* @param timestamp 时间戳
* @param nonce 随机数
* @return
*/
public static boolean validSign(String signature, String tocken, String timestamp, String nonce) {
String[] arr = new String[] { tocken, timestamp, nonce };
//对token、timestamp、nonce 进行字典排序,并拼接成字符串
Arrays.sort(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
MessageDigest md = null;
String tmpStr = null;
try {
md = MessageDigest.getInstance("SHA-1");
// 将三个参数字符串拼接成一个字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
tmpStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
content = null;
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
private static String byteToStr(byte[] byteArray) {
String rst = "";
for (int i = 0; i < byteArray.length; i++) {
rst += byteToHex(byteArray[i]);
}
return rst;
}
private static String byteToHex(byte b) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[2];
tempArr[0] = Digit[(b >>> 4) & 0X0F];
tempArr[1] = Digit[b & 0X0F];
String s = new String(tempArr);
return s;
}
public static String signature(SortedMap<String,String> items){
StringBuilder forSign= new StringBuilder();
for(String key:items.keySet()){
forSign.append(key).append("=").append(items.get(key)).append("&");
}
forSign.setLength(forSign.length()-1);
String result = encryptSHA1(forSign.toString());
return result;
}
public static String encryptSHA1(String content){
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(content.getBytes());
byte messageDigest[] = digest.digest();
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 null;
}
public static Map<String, String> sign(String jsapi_ticket, String url) {
Map<String, String> ret = new HashMap<String, String>();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
//注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonce_str +
"×tamp=" + timestamp +
"&url=" + url;
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
return ret;
}
public static Map<String, String> sign(String jsapi_ticket, String url,String nonce_str,String timestamp) {
Map<String, String> ret = new HashMap<String, String>();
String string1;
String signature = "";
//注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonce_str +
"×tamp=" + timestamp +
"&url=" + url;
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
return ret;
}
//生成签名
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;
}
//生成nonce_str
public static String create_nonce_str() {
return UUID.randomUUID().toString();
}
//生成timestamp
public static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
}