最全面的调用微信的扫一扫功能(java 排坑版)

最近碰到了这么一个需求,说是在前端页面调用手机本地的相机,扫描二维码这么一个需求,对于我一个后端来说,

这实在是难,难于上青天,但是决不能说一个不字.我说可以使用微信的扫码工具吗,这样可以方便一点,...(起码有个思路)

看着微信文档,一步一步坑下去.不对,是走下去.

这里我们用测试是公众号,方便测试.

首先配置自己的appID和appsecret,这里的测试帐号直接就给出了

第二步: 验证服务器,这个很简单,按照文档的规则验证就好了

第三步: 直接使用二级域名,不能添加http://前缀,或者是/XXX你自己写的接口

这里还有个问题就是下载一个XXXXX.txt文件放在项目的根目录下,这个txt文件在公众号里面设置js安全域名下面可以下载

第四步: 生成微信签名,这个很坑,要小心生成,这里面我使用的是google的guava做缓存,结合网上大佬的一个案例,仅限参考

public static Map<String, Object> sign(String url) throws Exception {    String ticket = getTicketToken(WeChatConstant.TICKET_TOKEN);    Map<String, Object> ret = new HashMap<String, Object>();    String nonce_str = create_nonce_str();    String timestamp = create_timestamp();    String string1;    String signature = "";    //注意这里参数名必须全部小写,且必须有序    string1 = "jsapi_ticket=" + ticket +"&noncestr=" + nonce_str +"&timestamp=" + timestamp +"&url=" + url;    System.out.println(string1);    try{        MessageDigest crypt = MessageDigest.getInstance("SHA-1");        crypt.reset();        crypt.update(string1.getBytes("UTF-8"));        signature = byteToHex(crypt.digest());        System.out.println(signature+"=====================");    }catch (NoSuchAlgorithmException e){        e.printStackTrace();    }catch (UnsupportedEncodingException e)    {        e.printStackTrace();    }    ret.put("url", url);    ret.put("nonceStr", nonce_str);    ret.put("timestamp", timestamp);    ret.put("signature", signature);    ret.put("jsapi_ticket", ticket);    ret.put("appId", WeChatConstant.APPID);    return ret;}
/** * 缓存其accessToken 和 ticketToken 的值 * * @param key * @return * @throws Exception */public static String getTicketToken(String key) throws Exception{    if (Objects.isNull(cache) || getCacheAccessToken(key).equals(WeChatConstant.TICKET_TOKEN)){        Gson gson = new Gson();        cache =  CacheBuilder.newBuilder().expireAfterWrite(7100,TimeUnit.SECONDS).build();        String accessToken = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+WeChatConstant.APPID +"&secret="+WeChatConstant.SECRET;        String httpResult = getHttpResult(accessToken);        AccessToken aT = gson.fromJson(httpResult, AccessToken.class);        String signUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+aT.getAccess_token()+"&type=jsapi";        String resultSign = getHttpResult(signUrl);        TicketToken ticket = gson.fromJson(resultSign, TicketToken.class);        cache.put(WeChatConstant.TICKET_TOKEN,ticket.getTicket());        return ticket.getTicket();    }else{        return getCacheAccessToken(key);    }}

/** * token失效,返回key值 * * @param key * @return * @throws ExecutionException */private static String getCacheAccessToken(String key) throws ExecutionException {    return cache.get(key, () -> {        return key;    });}

/** * 随机加密 * @param hash * @return */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;}/** * 获取访问地址链接返回值 */private static String getHttpResult(String url) {    String result = "";    HttpGet httpRequest = new HttpGet(url);    try {        HttpResponse httpResponse = HttpClients.createDefault().execute(httpRequest);        if (httpResponse.getStatusLine().getStatusCode() == 200) {            result = EntityUtils.toString(httpResponse.getEntity());        }    } catch (ClientProtocolException e) {        e.printStackTrace();        result = e.getMessage().toString();    } catch (IOException e) {        e.printStackTrace();        result = e.getMessage().toString();    }    return result;}/** * 产生随机串--由程序自己随机产生 * @return */private static String create_nonce_str() {    return UUID.randomUUID().toString();}/** * 由程序自己获取当前时间 * @return */private static String create_timestamp() {    return Long.toString(System.currentTimeMillis() / 1000);}
第五步:返回数据给前端校验 
/** * 调用扫一扫 验证用户信息 * * @param request * @return */@GetMapping("/signature")public WeChatEntity signature(HttpServletRequest request) throws Exception {    Map<String, Object> resMap = new HashMap<String, Object>();    resMap = SignatureUtil.sign(request.getRequestURL().);    request.setAttribute("nonceStr", resMap.get("nonceStr"));    request.setAttribute("timestamp", resMap.get("timestamp"));    request.setAttribute("signature", resMap.get("signature"));    request.setAttribute("appId", resMap.get("appId"));    request.setAttribute("url", resMap.get("url"));    request.setAttribute("jsapi_ticket",resMap.get("jsapi_ticket"));    WeChatEntity weChatEntity = new WeChatEntity(            resMap.get("appId").toString(),            resMap.get("timestamp").toString(),            resMap.get("nonceStr").toString(),            resMap.get("signature").toString());    return weChatEntity;}

这里有个坑的地方就是url的设定,这是你请求当前页面的url,可以在前端使用

location.href.split(‘#‘)[0]
打印出来.看看是否符合.
 
至此后端程序告一段落,下面就是前端程序了
1.导入依赖
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script><script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
 
html代码:
<input type="button"  value="扫一扫" id="scanQRCode">
 

js代码:

$(function() {          $.get("/signature", function(data){              alert(location.href.split(‘#‘)[0]);              // alert(data.appId         // +"======"+ data.timestamp         // +"======"+data.nonceStr         // +"======"+data.signature);
//上面是查看传来的数据是否符合要求              wx.config({                  // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。                  debug: false,                  // 必填,公众号的唯一标识                  appId: data.appId,                  // 必填,生成签名的时间戳                  timestamp: "" + data.timestamp,                  // 必填,生成签名的随机串                  nonceStr: data.nonceStr,                  // 必填,签名                  signature: data.signature,                  // 必填,需要使用的JS接口列表                  jsApiList: [‘checkJsApi‘, ‘scanQRCode‘]              });          });   wx.error(function(res) {      alert("出错了:" + res.errMsg); //这个地方的好处就是wx.config配置错误,会弹出窗口哪里错误,然后根据微信文档查询即可。   });   wx.ready(function() {      wx.checkJsApi({         jsApiList: [‘scanQRCode‘],         success: function(res) {

}      });      //点击按钮扫描二维码      document.querySelector(‘#scanQRCode‘).onclick = function() {         wx.scanQRCode({            needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,            scanType: ["qrCode"], // 可以指定扫二维码还是一维码,默认二者都有            success: function(res) {               var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果

alert("扫描结果:" + result);               window.location.href = result; //因为我这边是扫描后有个链接,然后跳转到该页面            }         });      };

});
});
以上就是网上一些大佬还有结合 详细说明的官方文档,花费了一下午时间,踩了N个坑总结出来的,希望大家都可以完成功能,
这样就可以开心的扫一扫啦,我先去扫一下了
 
有问题可以一起沟通,欢迎加我微信沟通,共同学习:AA19941205
 
放几个连接,大家可以参考下
微信签名工具
微信公众平台, config:invalid signature一直爆这个错误,求教如何解决?
 

原文地址:https://www.cnblogs.com/guyanzy/p/10363494.html

时间: 2024-07-28 16:53:27

最全面的调用微信的扫一扫功能(java 排坑版)的相关文章

asp.net调用微信扫一扫功能

1.页面引用http://res.wx.qq.com/open/js/jweixin-1.0.0.js 2.前台代码 function shaomiao() { wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印. appId: '', // 必填,公众号的唯一标识 timestamp: '<%=time %>', // 必填,生成签名的时

ASP.NET MVC做的微信WEBAPP中调用微信JSSDK扫一扫

今天做一个项目,是在微信上用的,微信WEB APP,里面用到了调用手机摄像头扫一扫二维码的功能,记得以前某个项目里写有的,但是找不到之前那个项目源码了,想复制粘贴也复制不了了,只好对着微信的那个开发文档重新再写过 ,顺便写个博客,以后碰到相同的问题直接复制博客里的代码就行了 以下是显示在微信上的页面: 以下是页面的代码,(用到了MUI): @{ Layout = "~/Views/Shared/_Layout.cshtml"; } <header class="mui-

微信选择图片、上传图片、下载图片、扫一扫接口调用源码

1.添加微信js引用: <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> 2.Html示例代码 <div style="margin: 200px 0px 0px 200px;"> <button id="chooseImage" class=&quo

调用微信扫一扫接口

---恢复内容开始--- 微信扫一扫,由JS去发起 在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js 请注意,如果你的页面启用了https,务必引入 https://res.wx.qq.com/open/js/jweixin-1.0.0.js ,否则将无法在iOS9.0以上系统中成功使用JSSDK wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会

前端JS调用微信扫一扫二维码

来源: 最近做一个项目,H5页面,在微信中打开,里面有个功能,就是  点击按钮弹出微信二维码扫一扫. 项目截图: 暂时没有图,下次再补上.就是页面点击按钮,弹出扫二维码的窗口 我只负责前端,所以只上前端代码,后端代码是java. HTML代码(如下):我用的是jQuery WeUI 框架快速开发(jQuery WeUI地址:http://jqweui.com/),所以a标签有样式 1 <a class="weui-btn weui-btn_primary submit-btn"

微信公众号调用扫一扫,识别二位码,并将扫码结果保存,传递到另外的网页

注意!这是微信公众号调用.需要微信配置信息.需要引入前置JS.http协议网站引入"http://res.wx.qq.com/open/js/jweixin-1.0.0.js",https协议网站引入"https://res.wx.qq.com/open/js/jweixin-1.0.0.js". 有错误跟我说一声. <!DOCTYPE html> <html> <head lang="en"> <met

微信支付:手机系统自带的浏览器,调用微信支付如何实现(非扫码)

Q:翻看了微信支付的api没发现支持h5调支付接口的情况(微信js除外),然后却发现美团的支付成功调用了,这是怎么实现的?     A: 使用微信H5支付即可.H5支付通过URL调起微信APP,不涉及到应用签名,可解决一次申请给多款APP使用的问题,看看现在游戏分发行业就知道了. 现在从官网申请到的APP支付(即通过SDK调起微信APP),如果适用在公司只有几款APP的情况,完全没问题.但是如果一家公司有几十几百款APP的话,使用APP支付就不合适了.(APP支付要求申请APPID,但每家公司主

Thinkphp调用微信扫一扫实例,学会再也不怕客户在微信提的奇葩要求了

哎!苦于客户一直要求,官方文档看起来又蛋疼,磨了一个下午整理出一套试用Thinkphp 调用微信扫一扫示例别小瞧这些代码哦,它们能帮你实现几乎所有的微信功能^_^1 先把WxSign 放到Thinkphp -- Vendor 目录下面2 把网站的Ip 授权,不然无法获取access_token值,那么jspai_ticket也将无法获取3 调用目录.调用目录.调用目录 重要的事情说三遍(大小写一定要明确)4 jsapi_ticket.php 和 access_token 一定要有读写的权限 使用

微信公众号开发纪要(4)-调用微信扫一扫功能

在微信公众号页面中调用微信扫一扫功能,就是调用微信JS-SDK.让JS-SDK完成调用摄像头扫描,然后我们将扫描结果进行业务操作.微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包.通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同时可以直接使用微信分享.扫一扫.卡券.支付等微信特有的能力,为微信用户提供更优质的网页体验.如何调用微信JS-SDK,在微信公众平台技术文档中的微信网页开发-->微信JS-SDK说明文档中有详细