700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 微信公众号开发之调起微信扫一扫接口

微信公众号开发之调起微信扫一扫接口

时间:2019-07-07 23:47:42

相关推荐

微信公众号开发之调起微信扫一扫接口

参考微信JS-SDK说明文档看到网上很多都说微信的说明文档很坑,在我看来,仔细阅读的话,介绍还是很全的。

1.首先在JSP页面引入http://res./open/js/jweixin-1.1.0.js

2.通过config接口注入权限验证配置

wx.config({debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。appId: '', // 必填,企业号的唯一标识,此处填写企业号corpidtimestamp: , // 必填,生成签名的时间戳nonceStr: '', // 必填,生成签名的随机串signature: '',// 必填,签名,见附录1jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2});

3.通过ready接口处理成功验证

wx.ready(function(){// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。});

4.通过error接口处理失败验证

wx.error(function(res){// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。});

5.调起微信扫一扫

wx.scanQRCode({desc: 'scanQRCode desc',needResult: 0, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有success: function (res) {// 回调}error: function(res){if(res.errMsg.indexOf('function_not_exist') > 0){alert('版本过低请升级')}}});

具体代码实现如下:

scanBarcode.jsp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html lang="zh-CN"><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=320.1,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"><head><link rel="stylesheet" href="http://203.195.235.76/jssdk/css/style.css"/><script src="http://res./open/js/jweixin-1.1.0.js"></script><script src="/jquery/2.0.0/jquery.js"></script><link rel="stylesheet" href="../../../resources/css/example.css"/><link rel="stylesheet" href="../../../resources/css/weui.min.css"/><link rel="stylesheet" href="../../../resources/css/borrowScan.css"/></head><body><div class="container" style="text-align: center;"><div class="body_bd body_fd"><a class="weui-btn weui-btn-primary weui-btn-zdy" id="scanQRCode1"><p>扫描条码</p></a></div></div><script type="text/javascript">$.ajax({url: "${pageContext.request.contextPath}/wechat/jsapisign",type: "post",data: {url: location.href.split('#')[0]},contentType: 'application/x-www-form-urlencoded;charset=utf-8',async: true,success: function (data) {wx.config({debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。appId: data.appid, // 必填,公众号的唯一标识timestamp: data.timestamp, // 必填,生成签名的时间戳nonceStr: data.nonceStr, // 必填,生成签名的随机串signature: data.signature,// 必填,签名,见附录1jsApiList: ["scanQRCode"] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2});}});wx.ready(function () {// 9.1.2 扫描二维码并返回结果document.querySelector('#scanQRCode1').onclick = function () {wx.scanQRCode({needResult: 1,desc: 'scanQRCode desc',success: function (res) {//扫码后获取结果参数赋值给Inputvar url = res.resultStr;//商品条形码,取","后面的if (url.indexOf(",") >= 0) {var tempArray = url.split(',');var barCode = tempArray[1];window.location.href = "https://open./connect/oauth2/authorize?appid=${appId}&redirect_uri=${basePath}/wechat/toBookDetail?barCode=" + barCode + "&response_type=code&scope=snsapi_base&state=BINDFACE#wechat_redirect";} else {alert("请对准条形码扫码!");}}});};});//初始化jsapi接口 状态wx.error(function (res) {alert("调用微信jsapi返回的状态:" + res.errMsg);});</script></body></html>

微信验签代码 WxController.java

/*** 微信验签* @param url* @return*/@RequestMapping(value = "/jsapisign", method = {RequestMethod.GET, RequestMethod.POST}, produces = MEDIATYPE_CHARSET_JSON_UTF8)@ResponseBodypublic String jsApiSign(String url) {//添加微信js签名信息Map<String, String> signMap = WXJsapiticket.jsApiSign(url);return JSON.toJSONString(signMap);}

用到的方法类

WXJsapiticket.java

public class WXJsapiticket {private static Logger logger = LoggerFactory.getLogger(WxController.class);/*** 微信jsapi验签* @param url* @return*/public static Map<String, String> jsApiSign(String url) {Map<String, String> ret = new HashMap<String, String>();String nonce_str = CheckUtil.create_nonce_str();String timestamp = CheckUtil.create_timestamp();String jsapi_ticket = getJsApiTicket();String string1 = CheckUtil.getString1(nonce_str,timestamp,jsapi_ticket,url);String signature = CheckUtil.getSha1(string1);ret.put("appid", WXConstants.APPID);//取你自己的公众号appidret.put("url", url);ret.put("jsapi_ticket", jsapi_ticket);ret.put("nonceStr", nonce_str);ret.put("timestamp", timestamp);ret.put("signature", signature);logger.info("jsApiSign------url=" + url + "-----jsapi_ticket=" + jsapi_ticket + "--------nonceStr=" + nonce_str + "--------timestamp=" + timestamp + "-------signature=" + signature);return ret;}public static String getJsApiTicket(){Map<String,Object> map = JsApiTicketCache.getInstance().getJsApiTicketAndExpiresIn();return (String) map.get("jsapi_ticket");}}

CheckUtil.java

public class CheckUtil {public static final String token = "xiaodou"; //开发者自行定义Token/*** 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式 (即 key1=value1&key2=value2…)拼接成字符串string1* @param nonce_str* @param timestamp* @param jsapi_ticket* @param url* @return*/public static String getString1(String nonce_str,String timestamp,String jsapi_ticket,String url){//1.定义数组存放nonce_str,timestamp,jsapi_ticket,urlString[] arr = {"noncestr="+nonce_str,"timestamp="+timestamp,"jsapi_ticket="+jsapi_ticket,"url="+url};//2.对数组进行排序Arrays.sort(arr);//3.生成字符串StringBuffer sb = new StringBuffer();for(String s : arr){sb.append(s);sb.append("&");}sb.deleteCharAt(sb.length()-1);return sb.toString();}public static String getSha1(String str){if(str==null||str.length()==0){return null;}char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};try {MessageDigest mdTemp = MessageDigest.getInstance("SHA1");mdTemp.update(str.getBytes("UTF-8"));byte[] md = mdTemp.digest();int j = md.length;char buf[] = new char[j*2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];buf[k++] = hexDigits[byte0 >>> 4 & 0xf];buf[k++] = hexDigits[byte0 & 0xf];}return new String(buf);} catch (Exception e) {// TODO: handle exceptionreturn null;}}public static String create_nonce_str() {return UUID.randomUUID().toString();}public static String create_timestamp() {return Long.toString(System.currentTimeMillis() / 1000);}}

JsApiTicketCatch.java(对jsapi_ticket的缓存可自行设置,redis或者存到数据库都是可行的)

/*** 缓存ticket*/public class JsApiTicketCache {//缓存jsapi_ticket的Map,map中包含jsapiTicket,expiresIn和缓存的时间戳timeprivate Map<String, String> map = new HashMap<String,String>();private static JsApiTicketCache jsApiTicketCache = null;private JsApiTicketCache() { }// 静态工厂方法public static JsApiTicketCache getInstance() {if (jsApiTicketCache == null) {jsApiTicketCache = new JsApiTicketCache();}return jsApiTicketCache;}public Map<String, String> getMap() {return map;}public void setMap(Map<String, String> map) {this.map = map;}/*** 获取 jsapi_ticket expires_in* @return*/public Map<String,Object> getJsApiTicketAndExpiresIn() {Map<String,Object> result = new HashMap<String,Object>();JsApiTicketCache jsApiTicketCache = JsApiTicketCache.getInstance();Map<String, String> map = jsApiTicketCache.getMap();String time = map.get("time");String jsapiTicket = map.get("jsapi_ticket");String expiresIn = map.get("expires_in");Long nowDate = new Date().getTime();if (jsapiTicket != null && time != null && expiresIn!=null) {//这里设置过期时间为微信规定的过期时间减去5分钟int outTime = (Integer.parseInt(expiresIn)-300) * 1000;if (nowDate - Long.parseLong(time) < outTime) {System.out.println("-----从缓存读取jsapi_ticket:" + jsapiTicket);//从缓存中拿数据为返回结果赋值result.put("jsapi_ticket", jsapiTicket);result.put("expires_in", expiresIn);}} else {JsapiTicket info = WeiXinUtil.getjsapiTicket();//实际中这里要改为你自己调用微信接口去获取jsapi_ticket和expires_inSystem.out.println("-----通过调用微信接口获取jsapi_ticket:" + info.getJsapiTicket());//将信息放置缓存中map.put("time", nowDate + "");map.put("jsapi_ticket", info.getJsapiTicket());map.put("expires_in", info.getExpiresIn()+"");//为返回结果赋值result.put("jsapi_ticket", info.getJsapiTicket());result.put("expires_in", info.getExpiresIn());}return result;}}

WeiXinUtil.java

jsapi_ticket_url="https://api./cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";//GET方式请求获得jsapi_ticket

/*** 获取jsapi_ticket* @return*/public static JsapiTicket getjsapiTicket() {JsapiTicket jsapiTicket = null ;String accessToken = (String) AccessTokenCache.getInstance().getAcessTokenAndExpiresIn().get("access_token");String requestUrl = WXConstants.jsapi_ticket_url.replace("ACCESS_TOKEN", accessToken);JSONObject jsonObject = httpRequest(requestUrl, "GET", null);// 如果请求成功if (null != jsonObject) {try {jsapiTicket = new JsapiTicket();jsapiTicket.setJsapiTicket(jsonObject.getString("ticket"));jsapiTicket.setExpiresIn(jsonObject.getInt("expires_in"));} catch (JSONException e) {jsapiTicket = null;// 获取token失败log.error("获取ticket失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));}}return jsapiTicket;}

accessToken的获取参照微信公众号开发之获取access_token,也可根据自己的定义获取。

JsapiTicket.java

public class JsapiTicket {private String id;private String jsapiTicket;private int expiresIn;public String getJsapiTicket() {return jsapiTicket;}public void setJsapiTicket(String jsapiTicket) {this.jsapiTicket = jsapiTicket;}public int getExpiresIn() {return expiresIn;}public void setExpiresIn(int expiresIn) {this.expiresIn = expiresIn;}public String getId() {return id;}public void setId(String id) {this.id = id;}}

在这里总结一下开发中需要注意的地方(我遇到的坑):

1.确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。

2.在生成string1时,拼接的参数均为小写,特别注意noncestr,而在jsp页面中为nonceStr(所有的参数一定要根据微信接口中的定义,否则会导致验签失败)。

3.验证签名是否正确,可在 http://mp./debug/cgi-bin/sandbox?t=jsapisign页面工具进行校验。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。