整理中....
要在微信公众号web里实现扫一扫,先查看 微信js-sdk说明文档
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="http://203.195.235.76/jssdk/css/style.css"/> <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"> </script> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script> <style type="text/css"> .desc{ color: red; } </style> </head> <body> <div class="lbox_close wxapi_form"> <h3 id="menu-scan">微信扫一扫</h3> <input id="timestamp" type="hidden" th:value="${timestamp}" /> <input id="noncestr" type="hidden" th:value="${nonceStr}" /> <input id="signature" type="hidden" th:value="${signature}" /> <input id="id_securityCode_input"> <button id="scanQRCode">扫码</button> </div> <script type="text/javascript"> $(function() { var timestamp = $("#timestamp").val();//时间戳 var nonceStr = $("#noncestr").val();//随机串 var signature = $("#signature").val();//签名 wx.config({ debug : true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId : '*****', // 必填,公众号的唯一标识 timestamp : timestamp, // 必填,生成签名的时间戳 nonceStr : nonceStr, // 必填,生成签名的随机串 signature : signature,// 必填,签名,见附录1 jsApiList : [ 'scanQRCode' ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); document.querySelector('#scanQRCode').onclick = function() { wx.scanQRCode({ desc: 'scanQRCode desc', needResult : 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果, scanType : [ "qrCode", "barCode" ], // 可以指定扫二维码还是一维码,默认二者都有 success : function(res) { var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果 document.getElementById("id_securityCode_input").value = result;//将扫描的结果赋予到jsp对应值上 alert("扫描成功::扫描码=" + result); } }); }; }); </script> </body> </html>
整理中...
import rg.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import java.util.Map; @Controller @RequestMapping public class jsApiController { @Autowired @Qualifier("wxService") private WxService wxService; @Autowired private WxUserService wxUserService; @Autowired @Qualifier("wxJsService") private WxJsService wxJsService; @GetMapping(value = "scanJsApi") public String scanJsApi(Model model) { String url = "http://"+Constants.AppDomain+ "/scanJsApi"; Map<String, String> ret = wxJsService.sign(url); for (Map.Entry entry : ret.entrySet()) { model.addAttribute(entry.getKey().toString(), entry.getValue()); } return "scan.html"; } }
整理中...
网页往下滑到底部:附录6-DEMO页面和示例代码,看demo示例
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Formatter; import java.util.HashMap; import java.util.Map; import java.util.UUID; @Component("wxJsService") @Transactional public class JsApiService{ @Autowired @Qualifier("wxService") private WxService wxService; public Map<String, String> sign(String url) { Map<String, String> ret = new HashMap<String, String>(); String jsapiTicket = wxService.getJsApiTicket(); //这里的jsapi_ticket是获取的jsapi_ticket。 String nonceStr = createNonceStr(); String timestamp = createTimestamp(); String string1; String signature = ""; //注意这里参数名必须全部小写,且必须有序 string1 = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url=" + url; System.out.println("string1:"+string1); try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(string1.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } ret.put("url", url); ret.put("jsapi_ticket", jsapiTicket); ret.put("nonceStr", nonceStr); ret.put("timestamp", timestamp); ret.put("signature", signature); ret.put("appId", "wx4c544fd0d116dedd"); return ret; } 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 createNonceStr() { return UUID.randomUUID().toString(); } private static String createTimestamp() { return Long.toString(System.currentTimeMillis() / 1000); } }
整理中...
前期获得access_token缓存,这里要根据access_token获取jspapi_ticket,
import net.sf.json.JSONObject; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; /** * Created by zxl on 2017/11/10. */ @Service public class WechatUtil { /** * 获得jsapi_ticket */ public static String getJsApiTicket(String token) { String url = Constants.JSAPI_TICKET + "?access_token=" + token + "&type=jsapi"; String response = OkHttpUtil.doGet(url); if (StringUtils.isBlank(response)) { return null; } JSONObject jsonObject = JSONObject.fromObject(response); System.out.println(response); String ticket = jsonObject.getString("ticket"); return ticket; } }
整理中...
把返回的ticket存在缓存中,需要就从缓存中调,
import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @Component("wxService") @Transactional public class WxService { @Autowired private CacheService cacheService; public String getJsApiTicket(){ CacheObjectType cacheObject = CacheObjectType.WX_TOKEN; String ticket = cacheService.get(cacheObject.getPrefix()+"jsapi_ticket"); if(StringUtils.isBlank(ticket)){ ticket = WechatUtil.getJsApiTicket(getToken()); cacheService.put(cacheObject.getPrefix()+"jsapi_ticket",ticket, cacheObject.getExpiredTime()); } return ticket; } }
整理中..
缓存部分
public enum CacheObjectType { VERIFY_CODE("sms:S:code:", 60 * 5), WX_TOKEN("wx:S:token", 7000); private String prefix; private int expiredTime; CacheObjectType(String prefix, int expiredTime) { this.prefix = prefix; this.expiredTime = expiredTime; } public String getPrefix() { return prefix; } public int getExpiredTime() { return expiredTime; } }
代码折叠真难用,累死我啦