整理中....
要在微信公眾號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; } }
代碼折疊真難用,累死我啦