test.jsp 页面文件
WxController.java 后端逻辑代码
一、JS-SDK集成及验证
1.前端引入js文件
<script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
2.为JS-SDK注入配置信息
wx.config({
beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: configData['appId'], // 必填,企业微信的corpID
timestamp: configData['timestamp'], // 必填,生成签名的时间戳
nonceStr: configData['noncestr'], // 必填,生成签名的随机串
signature: configData['signature'],// 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: ['getLocation'] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来,这里我们调用地理位置接口
});
以上需要配置的信息中,beta和debug为固定值,其余项产生方式如下:
appId:企业微信管理员后台企业ID
timestamp、nonceStr、signature:后台生成。后端代码调用逻辑为WxController->调用WxService接口(WxServiceImpl为实现类)->调用WxDao接口(WxDaoImpl为实现类),代码如下:
Controller层
WxController.java
/**
* 微信初始化参数获取接口
* @param url
* @param req
* @param res
* @return
*/
@ResponseBody
@RequestMapping(value="/getConfigParam",produces="text/html;charset=UTF-8")
public String getConfigParam(String url,HttpServletRequest req,HttpServletResponse res) {
//获取access_token
String access_token=wxService.getToken();
//获取企业ticket
String corpTicket=wxService.getCorpTicket(access_token);
JSONObject jsStr = JSONObject.fromObject(corpTicket);
String jsapi_ticket=(String)jsStr.get("ticket");
//随机字符串
String noncestr=getRandomString(10);
//时间戳
String timestamp=String.valueOf(System.currentTimeMillis());
//String timestamp=String.valueOf(new Date().getTime());
//获取签名字符串
String signature=signature(jsapi_ticket,noncestr,timestamp,url);
//构造参数集合map
Map<String,String> map=new HashMap<String,String>();
map.put("appId", "ww150a183aef2050ad");
map.put("noncestr", noncestr);
map.put("timestamp", timestamp);
map.put("signature", signature);
//生成返回值
JSONObject jo=JSONObject.fromObject(map);
String result=jo.toString();
return result;
}
//签名字符串生成函数
public String signature(String jsapi_ticket,String noncestr,String timestamp,String url) {
String str="jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"×tamp="+timestamp+"&url="+url;
//sha1加密
String signature=getSha1(str);
return signature;
}
Service层
WxService.java接口
public String getToken();
public String getCorpTicket(String access_token);
WxServiceImpl.java(实现WxService.java接口)
@Override
public String getToken() {
String ID="##";//##为企业ID
String SECRET="##";//##为企业微信中应用的Secret
String param="corpid="+ID+"&corpsecret="+SECRET;
String getTokenUrl="https://qyapi.weixin.qq.com/cgi-bin/gettoken";
return wxDao.getToken(getTokenUrl,param);
}
@Override
public String getCorpTicket(String access_token) {
String getCorpTicketUrl="https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket";
JSONObject jsStr = JSONObject.fromObject(access_token);
String tokenStr=(String)jsStr.get("access_token");
String param="access_token="+tokenStr;
String corpTicket=wxDao.getCorpTicket(getCorpTicketUrl, param);
return corpTicket;
}
Dao层
WxDao.java接口
public String getToken(String url, String param);
public String getCorpTicket(String getCorpTicketUrl,String param);
WxDaoImpl.java(实现WxDao.java接口)我这里采用的是数据库保存的方式,将sccess_tokenbao存在StaticParam表里,查询时看距离上次存储是否超过了7200s,如果过期则重新请求获取后保存。
/**
* 获得access_token
* param:"corpid=ID&corpsecret=SECRET"
*/
@Override
public String getToken(String getTokenUrl,String param) {
String result="";//包含access_token的字符串
//查找数据表staticParam,看是否已有token且未过期
String sql="SELECT * FROM STATICPARAM where key='access_token'";
Query query=sessionFactory.getCurrentSession().createSQLQuery(sql).addEntity(StaticParam.class);
ArrayList<StaticParam> rt=(ArrayList<StaticParam>)query.list();
if(rt.size()==0) {
//未保存access_token,请求新token并写入
String data=sendGet(getTokenUrl,param);
StaticParam staticParam=new StaticParam();
staticParam.setKey("access_token");
staticParam.setValue(data);
staticParam.setTime(new Date().getTime());
Session session=sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String newId=(String)session.save(staticParam);
tx.commit();
session.close();
result=data;
}else {
//已有token,检查是否过期,当前时间戳-保存时间戳 7200s
long interval=new Date().getTime()-rt.get(0).getTime();
if(interval>=7200000) {
//重新获取并写入
String data=sendGet(getTokenUrl,param);
StaticParam staticParam=new StaticParam();
staticParam.setId(rt.get(0).getId());
staticParam.setKey("access_token");
staticParam.setValue(data);
staticParam.setTime(new Date().getTime());
Session session=sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.update(staticParam);
tx.commit();
session.close();
result=data;
}else {
//直接数据库中取值
result=rt.get(0).getValue();
}
}
return result;
}
/**
* 获取企业ticket
* @param getCorpTicketUrl 请求URL:https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN
* @return
*/
public String getCorpTicket(String getCorpTicketUrl,String param) {
String result="";//包含corpTicket的字符串
//查找数据表staticParam,看是否已有corpTicket且未过期
String sql="SELECT * FROM STATICPARAM where key='corpTicket'";
Query query=sessionFactory.getCurrentSession().createSQLQuery(sql).addEntity(StaticParam.class);
ArrayList<StaticParam> rt=(ArrayList<StaticParam>)query.list();
if(rt.size()==0) {
//未保存corpTicket,请求新corpTicket并写入
String data=sendGet(getCorpTicketUrl,param);
StaticParam staticParam=new StaticParam();
staticParam.setKey("corpTicket");
staticParam.setValue(data);
staticParam.setTime(new Date().getTime());
Session session=sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String newId=(String)session.save(staticParam);
tx.commit();
session.close();
result=data;
}else {
//已有corpTicket,检查是否过期,当前时间戳-保存时间戳 7200s
long interval=new Date().getTime()-rt.get(0).getTime();
if(interval>=7200000) {
//重新获取并写入
String data=sendGet(getCorpTicketUrl,param);
StaticParam staticParam=new StaticParam();
staticParam.setId(rt.get(0).getId());
staticParam.setKey("corpTicket");
staticParam.setValue(data);
staticParam.setTime(new Date().getTime());
Session session=sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.update(staticParam);
tx.commit();
session.close();
result=data;
}else {
//直接数据库中取值
result=rt.get(0).getValue();
}
}
return result;
}
二、高德地图API集成
test.jsp
准备工作:在高德后台注册成个人开发者,然后在【我的应用】中新建一个应用,获取Key,后面会用到。
1、引入高德地图js
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=#"></script>//#处为准备工作中获取的高德应用的Key值
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=#"></script>//#处为准备工作中获取的高德应用的Key值
2、在<head>中加入以下语句
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
3、js调用示例
//初始化地图
var map = new AMap.Map('container', {
center: [116.397428, 39.90923],
layers: [//只显示默认图层的时候,layers可以缺省
new AMap.TileLayer()//高德默认标准图层
],
zoom: 13
});
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
//console.log(latitude);
}
});
4、完整的test.jsp页面代码如下,供测试参考。
最全的调用说明还是要看官网的文档的哈~,此处附上官方调用示例 https://developer.amap.com/demo/javascript-api/example/layers/default
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script src="//cdn.bootcss.com/jquery/1.11.0/jquery.min.js"></script>
<script src="//cdn.bootcss.com/jquery-weui/0.8.3/js/jquery-weui.min.js"></script>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=f0c096320bf008abe63967af3f10cf1e"></script>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<style>
#container {width:100%; height: 80%; }
</style>
<body style="width:100%;height:300px;">
<div align="center">
<h1>地图测试页面</h1>
</div>
<div id="container">放置地图的容器</div>
</body>
<script type="text/javascript">
var configData="";
//获取微信初始化参数
$.ajax({
url:"#",//后端生成温馨js-sdk初始化参数的接口地址
type:"post",
data:{url:"#"},//test.jsp的访问路径
dataType:'text',
success:function(res){
//console.log(res);
var rt=eval('('+res+')');
configData=rt;
//console.log(configData);
//微信初始化
wx.config({
beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: configData['appId'], // 必填,企业微信的corpID
timestamp: configData['timestamp'], // 必填,生成签名的时间戳
nonceStr: configData['noncestr'], // 必填,生成签名的随机串
signature: configData['signature'],// 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: ['getLocation'] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
});
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
//console.log(latitude);
}
});
},
error:function(){
console.log("出错了");
}
})
//图层参数
var layer = new AMap.TileLayer({
zooms:[3,20], //可见级别
visible:true, //是否可见
opacity:1, //透明度
zIndex:0, //叠加层级
detectRetina:true //是否在高清屏下适配,true为是
})
//初始化地图
var map = new AMap.Map('container', {
center: [116.397428, 39.90923],
layers: [//只显示默认图层的时候,layers可以缺省
new AMap.TileLayer()//高德默认标准图层
],
zoom: 13
});
//地图点标记
marker = new AMap.Marker({
icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",//可替换自己的图片地址
position: [116.406315,39.908775],
offset: new AMap.Pixel(-13, -30)
});
marker.setAnimation('AMAP_ANIMATION_BOUNCE');
marker.setMap(map);
</script>
</html>