微信接口调用百度地图api实现微信公众号打卡
时间:2019-07-20
本文章向大家介绍微信接口调用百度地图api实现微信公众号打卡,主要包括微信接口调用百度地图api实现微信公众号打卡使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前言
因最近给的需求要在微信公众号完成考勤打卡,刚开始说根据员工连接公司的wifi去判断,网上查了下java好像没得这个功能,所以只能选择在地图来完成。
本人也是第一次接触微信公众号,所以刚开始动手比较困难,好在经过一番摸索还是完成了。这里记录下自己的地图方案。
准备工作
既然是微信公众号肯定是基于微信接口的,也不用想的那么复杂,其实就是基于前台weui样式+微信js接口。下面详细说明步骤。
首先需要在公众号设置功能设置中配置微信公众号js接口安全域名
按流程把文件放在项目工程静态资源下
另外在基本配置中查看开发者密码后设置IP白名单,否则后续调用jssdk会报自身IP不在白名单内的错误
获取微信接口回调的数据
1 public class GetWeChatUtil { 2 public static final String wechat_token_url = "https://api.weixin.qq.com/cgi-bin/token" 3 4 public static final String wechat_appid = "xxx"; 5 6 public static final String wechat_secret = "xxx"; 7 8 public static final String wechat_token_grant_type = "client_credential"; 9 10 public static final String wechat_jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"; 11 12 public static final String wechat_jsapi_ticket_type = "jsapi"; 13 14 public static Map<String,Object> getWeChatToken(){ 15 Map<String,Object> map = new HashMap<>(); 16 try { 17 Map<String,String> params = new HashMap<String, String>(); 18 String ss = HttpConnectionUtil.httpsSendPost(wechat_token_url + "?grant_type=" + wechat_token_grant_type+"&appid="+wechat_appid+"&secret="+wechat_secret, null, "", "UTF-8", null); 19 System.out.println("----获取token返回信息:"+ss); 20 JSONObject json = JSONObject.parseObject(ss); 21 if(json.containsKey("access_token")){ 22 map.put("token", json.get("access_token")); 23 map.put("expires", json.get("expires_in")); 24 } 25 } catch (Exception e) { 26 e.printStackTrace(); 27 } 28 return map; 29 } 30 31 public static Map<String,Object> getJsapiTicket(String token) { 32 Map<String,Object> map = new HashMap<String, Object>(); 33 try { 34 Map<String,String> params = new HashMap<>(); 35 params.put("access_token", token); 36 params.put("type", "jsapi"); 37 String ss = HttpConnectionUtil.httpsSendPost(wechat_jsapi_ticket_url + "?access_token=" + token + "&type=" + wechat_jsapi_ticket_type, null, "", "UTF-8", null); 38 System.out.println("----获取JsapiTicket返回信息:"+ss); 39 JSONObject json = JSONObject.parseObject(ss); 40 if (json.getIntValue("errcode") == 0) { 41 map.put("ticket", json.get("ticket")); 42 map.put("expires", json.get("expires_in")); 43 } 44 }catch (Exception e) { 45 e.printStackTrace(); 46 } 47 return map; 48 } 49 50 public static Map<String, String> sign(String jsapi_ticket, String url) { 51 Map<String, String> ret = new HashMap<>(); 52 String nonce_str = create_nonce_str(); 53 String timestamp = create_timestamp(); 54 String string1; 55 String signature = ""; 56 57 string1 = "jsapi_ticket=" + jsapi_ticket + 58 "&noncestr=" + nonce_str + 59 "×tamp=" + timestamp + 60 "&url=" + url; 61 try { 62 MessageDigest crypt = MessageDigest.getInstance("SHA-1"); 63 crypt.reset(); 64 crypt.update(string1.getBytes("UTF-8")); 65 signature = byteToHex(crypt.digest()); 66 } 67 catch (NoSuchAlgorithmException e) { 68 e.printStackTrace(); 69 } 70 catch (UnsupportedEncodingException e) { 71 e.printStackTrace(); 72 } 73 74 ret.put("url", url); 75 ret.put("jsapi_ticket", jsapi_ticket); 76 ret.put("nonceStr", nonce_str); 77 ret.put("timestamp", timestamp); 78 ret.put("signature", signature); 79 80 return ret; 81 } 82 83 private static String byteToHex(final byte[] hash) { 84 Formatter formatter = new Formatter(); 85 for (byte b : hash) { 86 formatter.format("%02x", b); 87 } 88 String result = formatter.toString(); 89 formatter.close(); 90 return result; 91 } 92 93 private static String create_nonce_str() { 94 return UUID.randomUUID().toString(); 95 } 96 97 private static String create_timestamp() { 98 return Long.toString(System.currentTimeMillis() / 1000); 99 } 100 }
返回给前端调用微信接口必要参数
1 @Resource 2 private RedisTemplate<String,String> redisTemplate; 3 4 @RequestMapping("getwechatparams") 5 @ResponseBody 6 public Map<String,String> getParams(@RequestParam String url) { 7 if (redisTemplate.opsForValue().get("token") == null) { 8 Map<String,Object> map = GetWeChatUtil.getWeChatToken(); 9 if (map.get("token") != null) { 10 redisTemplate.opsForValue().set("token", map.get("token").toString(), Long.parseLong(map.get("expires").toString()), TimeUnit.SECONDS); 11 } 12 } 13 System.out.println("-----getWeToken:"+redisTemplate.opsForValue().get("token")); 14 if (redisTemplate.opsForValue().get("ticket") == null) { 15 Map<String,Object> mm = GetWeChatUtil.getJsapiTicket(redisTemplate.opsForValue().get("token")); 16 if (mm.get("ticket") != null) { 17 redisTemplate.opsForValue().set("ticket", mm.get("ticket").toString(), Long.parseLong(mm.get("expires").toString()), TimeUnit.SECONDS); 18 } 19 } 20 System.out.println("-----getWeTicket:"+redisTemplate.opsForValue().get("ticket")); 21 String weTicket = redisTemplate.opsForValue().get("ticket"); 22 Map<String, String> ret = GetWeChatUtil.sign(weTicket, url); 23 ret.put("appId", GetWeChatUtil.wechat_appid); 24 return ret; 25 }
前端百度地图显示
这里就只贴显示地图的关键性代码
1 <script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=ak密匙"></script> 2 <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> 3 4 <div id="allmap" style="width: 100%; height: 410px;"></div>
这里需要调用wx.getLocation()回调成功后的参数res中存放的是当前自身的GPS经纬度坐标,需要将GPS坐标系通过百度接口转换成百度坐标系
1 $(function () { 2 $.ajax({ 3 async: false, 4 url: "/getwechatparams", 5 type: "POST", 6 data: { 7 "url": window.location.href 8 }, 9 dataType: "json", 10 success: function (bal) { 11 wx.config({ 12 debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 13 appId: bal.appId, // 必填,公众号的唯一标识 14 timestamp: bal.timestamp, // 必填,生成签名的时间戳 15 nonceStr: bal.nonceStr, // 必填,生成签名的随机串 16 signature: bal.signature,// 必填,签名,见附录1 17 jsApiList: ['openLocation', 'getLocation'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 18 }); 19 wx.ready(function () { 20 wx.getLocation({ // 获取微信接口中的当前坐标经纬度 21 type: 'wgs84', // GPS坐标 22 success: function (res) { 23 //alert("gps转换前:" + res.longitude + "," + res.latitude) 24 25 var lnggg = ''; // 经度 26 var lattt = ''; // 纬度 27 var coordinate = ''; // 签到地点坐标 28 29 $.ajax({ 30 async: false, 31 url: "/get/location", 32 data: { 33 "longitude": res.longitude, 34 "latitude": res.latitude 35 }, 36 dataType: 'json', 37 success: function (responseData) { 38 lnggg = responseData.obj.lng; 39 lattt = responseData.obj.lat; 40 }, 41 error: function (responseData) { 42 alert(responseData.msg); 43 } 44 }); 45 46 // 百度地图API功能 47 var map = new BMap.Map("allmap"); 48 map.enableScrollWheelZoom(true); 49 50 //alert("gps转换后" + lnggg + ',' + lattt); 51 var point = new BMap.Point(lnggg, lattt); 52 53 var geo = new BMap.Geocoder(); 54 geo.getLocation(point, function (rs) { 55 var addComp = rs.addressComponents; 56 var address = addComp.city + addComp.district + addComp.street; // 当前自身详情街道地址 57 //alert(address) 58 }); 59 60 var geolocation = new BMap.Geolocation(); 61 geolocation.getCurrentPosition(function (r) { 62 r.point.lng = lnggg; 63 r.point.lat = lattt; 64 //alert("r.point.lng:" + r.point.lng + ",r.point.lat:" + r.point.lat); 65 if (this.getStatus() == BMAP_STATUS_SUCCESS) { 66 var mk = new BMap.Marker(r.point); // 创建标注 67 map.addOverlay(mk); // 将标注小红点添加到地图中 68 map.centerAndZoom(r.point, 16); // 缩放级别16 69 map.panTo(r.point); 70 71 coordinate = "116.40213223,40.10213223"; // 签到地点坐标 72 var arr = coordinate.split(","); 73 var lon = arr[0]; 74 var latt = arr[1]; 75 var pointAttendance = new BMap.Point(lon, latt); 76 r.point.lng = lon; 77 r.point.lat = latt; 78 var mk2 = new BMap.Marker(r.point); 79 var label = new BMap.Label("显示的文字", {offset: new BMap.Size(20, -10)}); 80 mk2.setLabel(label); 81 map.addOverlay(mk2); 82 map.addOverlay(pointAttendance); 83 mk2.setAnimation(BMAP_ANIMATION_BOUNCE); // 点跳动,没反应 84 85 circle = new BMap.Circle(pointAttendance, 200, { 86 fillColor: "blue", 87 strokeWeight: 1, 88 fillOpacity: 0.2, 89 strokeOpacity: 0.2 90 });// 显示签到点的位置(半径为200米的一个圆) 91 map.addOverlay(circle); 92 93 //计算当前位置与考勤点距离 94 var distance = map.getDistance(pointAttendance, point).toFixed(2); 95 //alert("距离为" + distance); 96 97 } else { 98 switch (this.getStatus()) { 99 case 2: 100 $.alert("位置结果未知 获取位置失败...", "加载地图失败", function () {}); 101 break; 102 case 3: 103 $.alert("导航结果未知 获取位置失败...", "加载地图失败", function () {}); 104 break; 105 case 4: 106 $.alert("非法密钥 获取位置失败...", "加载地图失败", function () {}); 107 break; 108 case 5: 109 $.alert("非法请求位置 获取位置失败...", "加载地图失败", function () {}); 110 break; 111 case 6: 112 $.alert("sorry 当前没有权限 获取位置失败...", "加载地图失败", function () {}); 113 break; 114 case 7: 115 $.alert("sorry 服务不可用 获取位置失败...", "加载地图失败", function () {}); 116 break; 117 case 8: 118 $.alert("sorry 请求超时 获取位置失败...", "加载地图失败", function () {}); 119 break; 120 } 121 } 122 }, { 123 enableHighAccuracy: true 124 }) 125 }, 126 error: function () { 127 $.alert("请检查GPS网络是否正常", "加载地图失败", function () {}); 128 } 129 } 130 ); 131 }); 132 } 133 }); 134 });
GPS坐标系转百度坐标系
1 @RequestMapping("get/location") 2 @ResponseBody 3 public AjaxResponse getLocation(String longitude, String latitude) { 4 try { 5 Map<String, String> mapLocation = ScHttpRequestUtil.getWpsToBaiduLocation(longitude, latitude); 6 return new AjaxResponse().setObj(mapLocation); 7 } catch (IOException e) { 8 log.error("{[]}", e); 9 return new AjaxResponse().setMsg("地址解析错误请重试!"); 10 } 11 } 12 13 public static synchronized Map<String, String> getWpsToBaiduLocation(String longitude, String latitude) throws IOException { 14 BufferedReader br = null; 15 StringBuffer sb = new StringBuffer(); 16 URL url = new URL("http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=" + longitude + "&y=" + latitude); 17 br = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8")); 18 String str = null; 19 while ((str = br.readLine()) != null) { 20 sb.append(str); 21 } 22 Map<String,String> map = (Map<String, String>) JSON.parse(sb.toString()); 23 24 Base64.Decoder decoder = Base64.getDecoder(); 25 26 String lng = new String(decoder.decode(map.get("x")), "utf-8"); 27 String lat = new String(decoder.decode(map.get("y")), "utf-8"); 28 Map<String, String> mapLocation = new HashMap<>(); 29 map.put("lng", lng); 30 map.put("lat", lat); 31 return map; 32 }
至此,基于微信接口实现百度地图的功能就完成了,功能就这么简单
原文地址:https://www.cnblogs.com/swanyf/p/11207729.html
- 【Java学习笔记之八】JavaBean中布尔类型使用注意事项
- BZOJ 1597: [Usaco2008 Mar]土地购买【斜率优化+凸包维护】
- BZOJ 1046: [HAOI2007]上升序列【贪心+二分状态+dp+递归】
- 【Java学习笔记之九】java二维数组及其多维数组的内存应用拓展延伸
- BZOJ 1293: [SCOI2009]生日礼物【单调队列】
- Javascript缓存投毒学习与实战
- 【Java学习笔记之十】Java中循环语句foreach使用总结及foreach写法失效的问题
- Codeforces 839B Game of the Rows【贪心】
- Codeforces 839A Arya and Bran【暴力】
- 【Java学习笔记之十一】Java中常用的8大排序算法详解总结
- 浅谈zip格式处理逻辑漏洞
- C/C++中peek函数的原理及应用
- 洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is He…【字符串+模拟】
- 洛谷 P1055 ISBN号码【字符串+模拟】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 数据导入和导出_1 MAT文件的保存和读取
- 论文研读-基于决策变量分析的大规模多目标进化算法
- 用python画 pareto front
- 一起来学演化计算-matlab基本数据结构struct
- 一起来学演化计算-matlab基本函数inf, isempty, round, floor, fix
- 一起来学演化计算-matlab基本函数randperm end数组索引
- 论文研读-基于决策变量聚类的大规模多目标优化进化算法
- 一起来学演化计算-matlab基本函数min
- 一起来学演化计算-matlab基本函数find
- 欧拉图和哈密顿图
- python 操作 txt 文件中数据教程[4]-python 去掉 txt 文件行尾换行
- java字符数组char[]和字符串String之间的转换
- python操作txt文件中数据教程[3]-python读取文件夹中所有txt文件并将数据转为csv文件
- python操作txt文件中数据教程[1]-使用python读写txt文件
- python循环删除列表元素常见错误与正确方法