preface
describe the general application scenario, that is, the mobile terminal of wechat needs to capture real-time images, upload them, and then transmit them to the background. Because we need images that can be displayed directly, we need to convert them into base encrypted images, and then display them in the img tag
summary
let's briefly talk about the role of JS-SDK. Wechat JS-SDK is a wechat based web development kit provided by wechat public platform for web developers. You can use the capabilities of mobile phone systems such as photography, map selection, voice and location through JS-SDK. At the same time, you can directly use the unique capabilities of wechat such as wechat sharing, scanning, card voucher and payment, The first step to using the JS SDK is to configure Wx Config interface. The first step is to reference jweixin-1.6.0.js File. If the above file is not available, download this file jweixin-1.6.0.js , the following is about how to configure Wx Config interface
Configure Wx Config interface
first Wx Config is equivalent to a master switch, or a global object. You can only use the interface attached to JS-SDK through correct authorization verification. In fact, it is equivalent to a permission verification. If the verification is successful, you can pass Wx The ready interface is implemented. If the verification fails, it enters Wx Error interface
wx.config interface injection permission verification configuration
wx.config({ debug: true, // When the debugging mode is enabled, the return values of all APIs called will be displayed in the client alert appId: '', // Required, the only sign of official account. timestamp: , // Required, time stamp to generate signature nonceStr: '', // Required, generate random string of signature signature: '',// Required, signature jsApiList: [] // Required, list of JS interfaces to be used });
get the timestamp of the signature generated by the first parameter (in fact, get the current time)
// time stamp String timestamp = Long.toString((new Date().getTime()) / 1000);
get the second signature random string (nothing special, UUID)
// Random string String nonceStr = UUID.randomUUID().toString();
get the third parameter signature!! This is more important. Signature = random string + ticket + timestamp + URL (current page), but we have obtained the random string and timestamp at the top. At the bottom, we only obtain the ticket and the URL of the current page. Finally, put them together
/** Four steps to obtain signature 1.Get current page URL 2.Get access_token parameter 3.Through access_token gets the ticket parameter 4.Put all the parameters together to get the signature **/ // 1.url (judge whether there are parameters. If there are parameters, splice the parameters, and the path must be configured in the white list) String params = request.getQueryString(); if(StringUtils.isEmpty(params)){ params=""; }else{ params="?"+params; } String url = "https://hb.sdpicc.com.cn"+request.getRequestURI()+params; // 2. toekn String access_token = AccessTokenAPI.getAccessToken(appId,appsecret); // 3.ticket String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi"; JSONObject jsonObject = HttpRequestUtil.httpRequest(urlStr, EnumMethod.GET.name(), null); String ticket = jsonObject.getString("ticket"); // 4.signature String signature = getsig(nonceStr,ticket,timestamp,url); // Finally, put it into the map and transfer it to the page Map<String,Object> map = new HashMap<String,Object>(); map.put("appId",appId); map.put("timestamp",timestamp); map.put("nonceStr",nonceStr); map.put("signature",signature);
define the AccessToken entity class and obtain access_tocken parameter (step 2)
// AccessToken entity class @Data public class AccessToken { // Obtained credentials private String token; // Voucher validity time, unit: seconds private int expiresIn; }
/** * Public platform common interface tool class * */ public class AccessTokenAPI { // GET WeChat official account: access_ The interface address (GET) of token is limited to 2000 (times / day) public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; /** * Get access_token */ public static AccessToken getAccessToken(String appid, String appsecret) { AccessToken accessToken = null; String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret); JSONObject jsonObject = HttpRequestUtil.httpRequest(requestUrl,EnumMethod.GET.name(), null); if (jsonObject == null) { jsonObject = HttpRequestUtil.httpRequest(requestUrl,EnumMethod.GET.name(), null); } // If the request is successful if (null != jsonObject) { try { accessToken = new AccessToken(); accessToken.setToken(jsonObject.getString("access_token")); accessToken.setExpiresIn(jsonObject.getInteger("expires_in")); } catch (JSONException e) { accessToken = null; // Failed to get token } } return accessToken; } }
tool class for splicing signature (step 4)
private static String getsig(String noncestr,String jsapi_ticket,String timestamp,String url){ String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + noncestr, "url=" + url }; Arrays.sort(paramArr); // Concatenate the sorted results into a string String content = paramArr[0].concat("&"+paramArr[1]).concat("&"+paramArr[2]) .concat("&"+paramArr[3]); String gensignature = null; try { MessageDigest md = MessageDigest.getInstance("SHA-1"); // sha1 encrypt the spliced string System.out.println("Splice encrypted signature:"+content); byte[] digest = md.digest(content.getBytes()); gensignature = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } // Compare sha1 encrypted string with signature if (gensignature != null) { return gensignature;// Return signature } else { return "false"; } } /** * Converts a byte array to a hexadecimal string * * @param byteArray * @return */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * Converts bytes to hexadecimal strings * * @param mByte * @return */ private static String byteToHexStr(byte mByte) { char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; }
the fourth jsApiList is actually the name of the interface to be called. Just put it in it
Complete code
this is to get Wx Config authorization verification complete code
@Service public class WxConfigUtils { @Value("${appId}") private String appId; @Value("${appSecret}") private String appSecret; public Map<String,Object> getWxconfig(HttpServletRequest request){ String params = request.getQueryString(); if(StringUtils.isEmpty(params)){ params=""; }else{ params="?"+params; } String url = "https://xxx.xx.cn"+request.getRequestURI()+params; //request.getRequestURL().toString(); Map<String,Object> map = new HashMap<String,Object>(); // time stamp String timestamp = Long.toString((new Date().getTime()) / 1000); // Random string String nonceStr = UUID.randomUUID().toString(); // Get access_token String access_token = AccessTokenAPI.getAccessToken(appId,appSecret); // Get jstl according to Toker String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi"; JSONObject jsonObject = HttpRequestUtil.httpRequest(urlStr, EnumMethod.GET.name(), null); String ticket = jsonObject.getString("ticket"); System.out.println("Parameters to encrypt:"+nonceStr+" "+ticket+" "+timestamp+" "+url); String signature = getsig(nonceStr,ticket,timestamp,url); map.put("appId",appId); map.put("timestamp",timestamp); map.put("nonceStr",nonceStr); map.put("signature",signature); return map; } private static String getsig(String noncestr,String jsapi_ticket,String timestamp,String url){ String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + noncestr, "url=" + url }; Arrays.sort(paramArr); // Concatenate the sorted results into a string String content = paramArr[0].concat("&"+paramArr[1]).concat("&"+paramArr[2]) .concat("&"+paramArr[3]); String gensignature = null; try { MessageDigest md = MessageDigest.getInstance("SHA-1"); // sha1 encrypt the spliced string System.out.println("Splice encrypted signature:"+content); byte[] digest = md.digest(content.getBytes()); gensignature = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } // Compare sha1 encrypted string with signature if (gensignature != null) { return gensignature;// Return signature } else { return "false"; } } /** * Converts a byte array to a hexadecimal string * * @param byteArray * @return */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * Converts bytes to hexadecimal strings * * @param mByte * @return */ private static String byteToHexStr(byte mByte) { char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } }
Front end page implementation
the complete front-end interface does not upload style files. Just write styles and put a picture
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Call the enterprise wechat image upload interface</title> <!--Upload pictures css--> <link rel="stylesheet" href="../css/style.css" /> </head> <body> <header class="upload-hedaer"> <a href="javaScript:history.back(-1)" class="upload-fh"></a> <div>upload</div> <div>ยทยทยท</div> </header> <section class="upload-section"> <article class="upload-piclist"> <div class="upload-file" id="uploadfile"></div> </article> </section> <script src="../js/jweixin-1.2.0.js" type="text/javascript" charset="utf-8"></script> <script src="../js/jquery-3.0.0.min.js" type="text/javascript" charset="utf-8"></script> <script src="../js/wxconfig.js" type="text/javascript" charset="utf-8"></script> </body> <script type="text/javascript"> /** In this place, we only need to refer to the page to be used 1.chooseImage: And the interface for taking pictures or selecting pictures from mobile photo albums 2.getLocalImgData: Get local picture interface **/ wx.config({ debug: true, // The production environment needs to turn off the debug mode appId: "[[${appId}]]", // appID = corpID, viewed through wechat service number / enterprise wechat background timestamp: "[[${timestamp}]]", // Timestamp when the signature was generated nonceStr: "[[${nonceStr}]]", // Generate a signed random string signature: "[[${signature}]]", // autograph jsApiList: [ // List of JS interfaces to be called 'chooseImage', 'getLocalImgData' ] }); </script> </html>
our Wx The ready interface is written as a separate JS file. Considering that more than one page will use this function, it is written as a public method
wx.ready(function(){ var piclist = document.getElementsByClassName('upload-piclist')[0]; //Bind onclick event to upload Icon $("#uploadfile").click(function(){ // Call interface wx.chooseImage({ count: 1, // Default 9 sizeType: ['original', 'compressed'], // You can specify whether to use the original or compressed image. Both are available by default sourceType: ['album', 'camera'], // You can specify whether the source is an album or a camera. Both are available by default success: function(res) { wx.getLocalImgData({ localId: res.localIds[0], // localID of the picture success: function(res) { var localData = res.localData; var imageBase64 = ''; if (localData.indexOf('data:image') == 0) { //The direct assignment of Apple generates' data: image / jpeg 'by default; Base64, 'head splice imageBase64 = localData; } else { //This is the only pit in Andrews! Before splicing, you need to globally replace the newline character of localData //At this time, a normal base64 image path is perfectly generated and assigned to the src of img imageBase64 = 'data:image/jpeg;base64,' + localData.replace(/\n/g, ''); } var html = document.createElement('div'); html.innerHTML = '<img id="image" src=' + imageBase64 + ' alt="">' piclist.appendChild(html); } }); } }); }) });