您的位置:首页 > 移动开发 > 微信开发

Java 微信JS SDK 入门(网页内获取地理信息)

2016-07-29 00:00 375 查看
摘要: 本文介绍微信JSSDK入门配置,以获取地理信息为demo。并讲讲本人在入门过程中所遇到的坑

阅读前,请保证对微信开发有过了解。

1.准备

1.一个微信公众(本文以测试号为例子)

2.微信web开发者工具,官网有下载

2.新建一个jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script>
//用于测试时确保URL与后端的一样,这很重要!!!
alert("当前URL:"+location.href.split('#')[0]);
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '${appId}', // 必填,企业号的唯一标识,此处填写企业号corpid
timestamp: parseInt("${timestamp}",10), // 必填,生成签名的时间戳
nonceStr: '${noncestr}', // 必填,生成签名的随机串
signature: '${signature}',// 必填,签名,见附录1
jsApiList: ['getLocation'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
wx.ready(function(){
});

wx.error(function(res){
});
</script>
</head>
<body>
<button id="getBBS" style="width:1000px;height:600px;font-size:150px;" onclick="submitOrderInfoClick();">获取地理位置</button>
</body>
<script type="text/javascript">
function submitOrderInfoClick(){
wx.getLocation({
success: function (res) {
alert("获取地理位置成功,经纬度为:(" + res.latitude + "," + res.longitude + ")" );
},
fail: function(error) {
AlertUtil.error("获取地理位置失败,请确保开启GPS且允许微信获取您的地理位置!");
}
});
}
</script>
</html>

上面可以看到,前端想要调用js sdk,就需要后台提供下面几个信息

appId 这个不用说了吧

timestamp 时间戳,开发者自己生成

nonceStr 随机字符串,开发者自己生成

signature 签名,需要计算出来,这个才是最重要的

备注一下坑:前端的参数名注意书写规则。前端参数命名以驼峰式命名,后台就以全小写。。。。大公司就不能专业一点吗

3.后台Java代码(Spring MVC)

详细的注释代码都有

@RequestMapping("/wx/jsSDK")
public String jsSDK(Model model, HttpServletRequest request) {
//获取jsSDK临时票据ticket
String ticket = CommonUtil.getJsApiTicket();
log.info(ticket);
//计算签名signature
String noncestr = UUID.randomUUID().toString();//生成一段随机数
String timestamp = Long.toString(System.currentTimeMillis() / 1000);//生成timestamp
//获取当前请求url,#前面所有
String url;
String queryString = request.getQueryString();//URL参数,即?后的xx=xxx
if (queryString == null) {
queryString = "";
} else {
queryString = "?" + queryString;
}

url = request.getScheme() + "://"
+ request.getServerName() + ":"
+ request.getServerPort()
+ request.getContextPath()
+ request.getServletPath()
+ queryString;
/*
注意,无论你的URL是否带参数,都必须判断他是否有参数
因为有时候微信跳转的时候会在你的URL后面加参数用于统计,
比如你的URL是 http://域名/项目名/xxx/jsSDK 跳转的时候微信会在后面加参数,变成 http://域名/项目名/xxx/jsSDK?nsukey=xxxxxxxx 这样,计算出来的签名就会不正确了,这也是坑之一

下面几句代码是方便测试用的,为什么?
以我为例,测试时候URL是http://127.0.0.1:8080/wx/jsSDK
发布的时候,URL是     http://域名/wx/jsSDK 发现什么了,端口80自动隐藏了,也就是说发布的时候,是不能把80写进去,不然计算出来的签名会出错
一句说完,这里的URL与你访问的URL 必须完全一致
*/

boolean degug = true;
//如果是正式发布,把“:80” 去掉
if (degug == false) {
url = url.replace(":80", "");
}
log.info("地址:" + url);

//把这些信息组合起来,使用SHA1加密,得到 signature
String str = "jsapi_ticket=" + ticket +
"&noncestr=" + noncestr +
"×tamp=" + timestamp +
"&url=" + url;
String signature = SignUtil.SHA1(str).toLowerCase();

//把信息传到前台
model.addAttribute("signature", signature);
model.addAttribute("timestamp", timestamp);
model.addAttribute("noncestr", noncestr);
model.addAttribute("appId", wxEnum.APPID.getValue());
return "jssdk";
}

上面调用了两个工具的方法

获取accessToken,这个就不贴出来

获取ticket的贴出来参考

SHA1加密,这个自己百度

public static String jsapi_ticket = null;
public static long time = 0;

public static String getJsApiTicket() {
if (jsapi_ticket != null) {
//ticket有效期7200s,无需在有效时间内重复申请。
if (((new Date().getTime() - time) / 1000) > 7000) {
return jsapi_ticket;
}
}
//获取token
Token token = CommonUtil.getToken(wxEnum.APPID.getValue(), wxEnum.APPSECRET.getValue());
String accessToken = token.getAccessToken();
//根据token获取ticket
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
String requestUrl = url.replace("ACCESS_TOKEN", accessToken);
// 发起GET请求获取凭证
JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
if (null != jsonObject) {
try {
jsapi_ticket = jsonObject.getString("ticket");
time = new Date().getTime();
return jsapi_ticket;
} catch (JSONException e) {
log.error("获取token失败" + jsonObject.getInt("errcode") + jsonObject.getString("errmsg"));
}
}
return null;
}

public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();

URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);

conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(GET/POST)
conn.setRequestMethod(requestMethod);

// 当outputStr不为null时向输出流写数据
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 = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
log.error("连接超时:{}", ce);
} catch (Exception e) {
log.error("https请求异常:{}", e);
}
return jsonObject;
}

开启tomcat,在微信开发工具里测试



看都这个提示,表示代码没问题,还需要到微信公众平台 设置的公众号的JS接口安全域名

为127.0.0.1:8080再次刷新即提示成功
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  微信开发
相关文章推荐