一 、准備工作
<1> 域名認證准備工作
在需要調用攝像頭的接口頁面引入微信的js,具體地址為:(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js
首先JS安全接口域名認證:
具體可參考開發文檔:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
填寫規則(必須是備案通過的域名):
若域名類似為:xxx.xxx.xxx.com 則接口域名為:xxx.xxx.com
若域名類似為:xxx.xxx.com 則接口域名為:xxx.com
若域名類似為:xxx.xxx.com:8080 則接口域名為:xxx.com:8080
<2> OCR識別准備工作
注冊百度雲服務賬號,網址:https://cloud.baidu.com/index.html?track=cp:npinzhuan|pf:pc|pp:left|ci:|pu:495
點擊智能控制台>>產品服務>>人工智能>>文字識別>>創建應用
填寫相關信息選擇對應的需求
點擊創建應用>>查看詳情:appid、apikey、secretkey是我們所需要的
二、具體代碼實現
在需要調用微信js的jsp頁面引入js,做如下操作:
1 $(function (){ 2 wx.config({ 3 debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,測試完成后需要關閉。 4 appId: $('#appId').val(), // 必填,公眾號的唯一標識 5 timestamp: $('#timestamp').val(), // 必填,生成簽名的時間戳 6 nonceStr: $('#nonceStr').val(), // 必填,生成簽名的隨機串 7 signature: $('#signature').val(),// 必填,簽名(加密后,下文有實現) 8 jsApiList: ['chooseImage', 'uploadImage'] // 必填,需要使用的JS接口列表,開發文檔上有所有接口名稱,根據需要選用就好。 9 }); 10 }); 11 12 13 function openCamera(){ 14 wx.chooseImage({ 15 count: 1, // 默認9 16 sizeType: ['original', 'compressed'], // 指定是原圖還是壓縮圖,默認都有 17 sourceType: ['album', 'camera'], // 指定來源是相冊還是相機,默認都有 18 success: function (res) { 19 var localIds = res.localIds; // 返回選定照片的本地ID列表,localId可以作為img標簽的src屬性顯示圖片 20 wx.uploadImage({ 21 localId: localIds.toString(), // 需要上傳的圖片的ID,由chooseImage接口獲得 22 isShowProgressTips: 1, // 進度提示 23 success: function (res) { 24 var mediaId = res.serverId; // 返回圖片的服務器端ID,即mediaId 25 //將獲取到的 mediaId 傳入后台 方法savePicture 26 $.post(path+"/getImage/savePicture",{"mediaId":mediaId,"tmp":"填寫證件的正反面參數"},function(res){ 27 //填寫你自己的業務邏輯 28 }); 29 }, 30 fail: function (res) { 31 alertModal('圖片上傳失敗,請重試'); 32 } 33 }); 34 } 35 }); 36 }
wx.config這個函數是進行js域名驗證所必須的操作,具體實現如下:
1 //-------------------------初始化js-sdk--------begin---------------------------- 2 SortedMap<Object, Object> params = new TreeMap<Object, Object>(); 3 String access_token = WechatAppUtil.getAccessToken(appid,appSecret);// 建議放redis放緩存中(access_token ) 4 String jsapi_ticket = WechatAppUtil.getJsapiTicket(access_token); 5 String noncestr = WechatSignUtil.getNonceStr(); 6 String timestamp = WechatSignUtil.getTimestamp(); 7 params.put("noncestr", noncestr); 8 params.put("jsapi_ticket", jsapi_ticket); 9 params.put("timestamp", timestamp); 10 StringBuffer url = cRequest.getRequestURL(); 11 Enumeration<String> headerNames = cRequest.getHeaderNames(); 12 if (headerNames != null) { 13 while (headerNames.hasMoreElements()) { 14 String header = headerNames.nextElement(); 15 log.info("Header: {}, Value={}", header, cRequest.getHeader(header)); 16 } 17 } 18 String httpFlag = cRequest.getHeader("X-Forwarded-Proto"); 19 if (httpFlag != null && httpFlag.equals("https")) { 20 url.replace(0, 5, "https"); 21 } 22 String queryString = cRequest.getQueryString(); 23 log.info("queryString={}", queryString); 24 if (StringUtil.isNotEmpty(queryString)) { 25 url.append("?").append(cRequest.getQueryString()); 26 } 27 params.put("url", url.toString()); 28 log.info("url---------------->:"+url.toString()); 29 String sign = WechatSignUtil.createSignBySha1(params); 30 log.info("sign---------------->:"+sign); 31 //-------------------------初始化js-sdk--------end---------------------------- 32 ModelAndView tView = new ModelAndView(LoginPageConstant.STAFF_REGIST2); 33 tView.addObject("appId", appid); 34 tView.addObject("timestamp", timestamp); 35 tView.addObject("nonceStr", noncestr); 36 tView.addObject("signature", sign); return tView;
1 /** 2 * @Title: getAccessToken 3 * @Description: 獲取公眾號access_token 4 * @param @param appId 5 * @param @param appSecret 6 * @param @return 7 * @return String 返回類型 8 * @throws 9 */ 10 public static String getAccessToken(String appId,String appSecret){ 11 final String param = "grant_type=client_credential" + "&appid=" + appId + "&secret=" + appSecret; 12 final String data = HttpClientUtil.get(GET_ACCESS_TOKEN_PATH, param); 13 JSONObject resultJson = JSON.parseObject(data); 14 String access_token = resultJson.getString("access_token"); 15 return access_token; 16 } 17 18 /** 19 * 20 * @Title: getJsapiTicket 21 * @Description: 獲取JsapiTicket 22 * @param @param access_token 23 * @param @return 24 * @return String 返回類型 25 * @throws 26 */ 27 public static String getJsapiTicket(String access_token){ 28 final String param = "access_token="+access_token+ "&type=jsapi"; 29 final String data = HttpClientUtil.get(GET_JSAPI_TICKET, param); 30 JSONObject resultJson = JSON.parseObject(data); 31 String jsapi_ticket = resultJson.getString("ticket"); 32 return jsapi_ticket; 33 }/** 34 * 35 * @Title: getNonceStr 36 * @Description: 生成隨機字符串 37 * @param @return 38 * @return String 返回類型 39 * @throws 40 */ 41 public static String getNonceStr() { 42 String currT = getCurrTime(); 43 String strT = currT.substring(8, currT.length()); 44 String strRandom = buildRandom(4) + ""; 45 return strT + strRandom; 46 } 47 48 49 /** 50 * 51 * @Title: buildRandom 52 * @Description: 生成隨機數 53 * @param @param length 54 * @param @return 55 * @return int 返回類型 56 * @throws 57 */ 58 public static int buildRandom(int length) { 59 int mm= 1; 60 double random = Math.random(); 61 if (random < 0.1) { 62 random = random + 0.1; 63 } 64 for (int i = 0; i < length; i++) { 65 mm= mm* 10; 66 } 67 return (int) ((random * mm)); 68 } 69 70 71 /** 72 * 73 * @Title: getCurrTime 74 * @Description: 獲取當前時間 75 * @param @return 76 * @return String 返回類型 77 * @throws 78 */ 79 public static String getCurrTime() { 80 Date date = new Date(); 81 SimpleDateFormat of= new SimpleDateFormat("yyyyMMddHHmmss"); 82 String s = of.format(date); 83 return s; 84 } 85 86 /** 87 * 88 * @Title: createSignBySha1 89 * @Description: 生成簽名 90 * @param @param params 91 * @param @return 92 * @return String 返回類型 93 * @throws 94 */ 95 @SuppressWarnings("rawtypes") 96 public static String createSignBySha1(SortedMap<Object, Object> params) { 97 StringBuffer sb = new StringBuffer(); 98 Set es = params.entrySet(); 99 Iterator it = es.iterator(); 100 while (it.hasNext()) { 101 Map.Entry entry = (Map.Entry) it.next(); 102 String k = (String) entry.getKey(); 103 String v = (String) entry.getValue(); 104 if (v != null && !v.equals("")) { 105 sb.append(k + "=" + v + "&"); 106 } 107 } 108 String result = sb.toString().substring(0, sb.toString().length()-1); 109 return getSHA1(result); 110 } 111 /** 112 * 113 * @Title: getTimestamp 114 * @Description: 獲取時間戳(秒) 115 * @param @return 參數 116 * @return String 返回類型 117 * @throws 118 */ 119 public static String getTimestamp() { 120 return String.valueOf(System.currentTimeMillis() / 1000); 121 } 122 123 124 /** 125 * 126 * @Title: getSHA1 127 * @Description: SHA1簽名生成 128 * @param @param str 129 * @param @return 參數 130 * @return String 返回類型 131 * @throws 132 */ 133 public static String getSHA1(String str){ 134 StringBuffer hexstr = new StringBuffer(); 135 try { 136 MessageDigest md = MessageDigest.getInstance("SHA-1"); 137 md.update(str.getBytes()); 138 byte[] digest = md.digest(); 139 String shaHex = ""; 140 for (int i = 0; i < digest.length; i++) { 141 shaHex = Integer.toHexString(digest[i] & 0xFF); 142 if (shaHex.length() < 2) { 143 hexstr.append(0); 144 } 145 hexstr.append(shaHex); 146 } 147 } catch (NoSuchAlgorithmException e) { 148 e.printStackTrace(); 149 } 150 return hexstr.toString(); 151 }
驗證完成后台實現如下:
1 /** 2 * 3 * @Title: savePicture 4 * @Description: 接收圖片 5 * @param @param request 6 * @param @return 7 * @return String 返回類型 8 * @throws 9 */ 10 @ResponseBody 11 @RequestMapping("/savePicture") 12 public String savePicture(HttpServletRequest request) { 13 String mediaId = request.getParameter("mediaId"); 14 String tmp = request.getParameter("tmp"); 15 String filename = saveImageToDisk(mediaId,tmp,request); 16 log.info("filename----------->:"+filename); 17 return "success"; 18 } 19 20 /** 21 * 22 * @Title: saveImageToDisk 23 * @Description: 存盤 24 * @param @param mediaId 25 * @param @return 26 * @return String 返回類型 27 * @throws 28 */ 29 private String saveImageToDisk(String mediaId,String tmp,HttpServletRequest request){ 30 String filename = ""; 31 InputStream inputStream = getMedia(mediaId); 32 byte[] data = new byte[1024]; 33 int len = 0; 34 FileOutputStream fileOutputStream = null; 35 try { 36 //服務器存圖路徑 37 String path = request.getServletContext().getRealPath("你需要存放的服務器路徑"); 38 filename = System.currentTimeMillis() + WechatSignUtil.getNonceStr() + ".jpg"; 39 fileOutputStream = new FileOutputStream(path + filename); 40 while ((len = inputStream.read(data)) != -1) { 41 fileOutputStream.write(data, 0, len); 42 } 43 WeChatUser idCardMsg = getIdCardMsg(tmp,path + filename); 44 } catch (IOException e) { 45 e.printStackTrace(); 46 } finally { 47 if (inputStream != null) { 48 try { 49 inputStream.close(); 50 } catch (IOException e) { 51 e.printStackTrace(); 52 } 53 } 54 if (fileOutputStream != null) { 55 try { 56 fileOutputStream.close(); 57 } catch (IOException e) { 58 e.printStackTrace(); 59 } 60 } 61 } 62 return filename; 63 } 64 65 /** 66 * 67 * @Title: getMedia 68 * @Description: 獲取圖片 69 * @param @param mediaId 70 * @param @return 參數 71 * @return InputStream 返回類型 72 * @throws 73 */ 74 private InputStream getMedia(String mediaId) { 75 String url = "https://api.weixin.qq.com/cgi-bin/media/get"; 76 String access_token = WechatAppUtil.getAccessToken("**********","*************"); 77 String params = "access_token=" + access_token + "&media_id=" + mediaId; 78 InputStream is = null; 79 try { 80 String urlNameString = url + "?" + params; 81 URL urlGet = new URL(urlNameString); 82 HttpURLConnection http = (HttpURLConnection) urlGet.openConnection(); 83 http.setRequestMethod("GET"); // 必須是get方式請求 84 http.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); 85 http.setDoOutput(true); 86 http.setDoInput(true); 87 http.connect(); 88 // 獲取文件轉化為byte流 89 is = http.getInputStream(); 90 } catch (Exception e) { 91 e.printStackTrace(); 92 } 93 return is; 94 } 95 96 /** 97 * 98 * @Title: getIdCardMsg 99 * @Description: 100 * @param @param tmp 101 * @param @param imgUrl 圖片路徑 102 * @param @return 103 * @return WeChatUser 返回類型 104 * @throws 105 */ 106 private WeChatUser getIdCardMsg(String tmp,String imgUrl){ 107 // 初始化一個AipOcr 108 AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY); 109 // 可選:設置網絡連接參數 110 client.setConnectionTimeoutInMillis(2000); 111 client.setSocketTimeoutInMillis(60000); 112 // 傳入可選參數調用接口 113 HashMap<String, String> options = new HashMap<String, String>(); 114 options.put("detect_direction", "true"); 115 options.put("detect_risk", "false"); 116 String idCardSide = tmp; 117 // 參數為圖片路徑 118 String image = imgUrl; 119 JSONObject res = client.idcard(image, idCardSide, options); 120 具體返回信息處理請參考開發文檔:https://cloud.baidu.com/doc/OCR/OCR-Java-SDK.html#.E6.8E.A5.E5.8F.A3.E8.83.BD.E5.8A.9B 121 }