package com.runmin.bajie.entity; /** * 憑證 * */ public class Token { // 接口訪問憑證 private String accessToken; // 憑證有效期,單位:秒 private int expiresIn; public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public int getExpiresIn() { return expiresIn; } public void setExpiresIn(int expiresIn) { this.expiresIn = expiresIn; } }
package com.runmin.bajie.entity; public class JsapiTicket { // 獲取到的憑證 private String ticket; // 憑證有效期,單位:秒 private int expiresIn; public String getTicket() { return ticket; } public void setTicket(String ticket) { this.ticket = ticket; } public int getExpiresIn() { return expiresIn; } public void setExpiresIn(int expiresIn) { this.expiresIn = expiresIn; } }
package com.runmin.bajie.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.URL; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import com.runmin.bajie.entity.JsapiTicket; import com.runmin.bajie.entity.Token; import net.sf.json.JSONException; import net.sf.json.JSONObject; public class TokenUtil { public final static String appid = "***********************************"; public final static String secret = "***********************************"; // 憑證獲取(GET),token_url獲取憑證接口的請求地址 public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?" + "grant_type=client_credential&" + "appid=" + appid + "&" + "secret=" + secret; /** * 發送https請求.定義了一個通用的HTTPS請求方法,用於發送HTTPS GET和POST請求 * 當調用公衆平臺的開發接口時,都須要傳入接口訪問憑證access_token * * @param requestUrl 請求地址 * @param requestMethod 請求方式(GET、POST) * @param outputStr 提交的數據 * @return */ public static JSONObject getTokenJsonObject(String requestUrl, String requestMethod, String outputStr){ JSONObject returnData = null; try { // 建立SSLContext對象,並使用咱們指定的信任管理器初始化 TrustManager[] tm = {new MyX509TrustManager()}; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 從上述SSLContext對象中獲得SSLSocketFactory對象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(ssf); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); // 設置請求方式(GET/POST) conn.setRequestMethod(requestMethod); // 當outputStr不爲null時向輸出流寫數據 if (null != outputStr) { OutputStream outputStream = conn.getOutputStream(); // 注意編碼格式 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 從輸入流讀取返回內容 InputStream inputStream = conn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } // 釋放資源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; conn.disconnect(); returnData = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { System.out.printf("鏈接超時:{}", ce); } catch (Exception e) { System.out.printf("https請求異常:{}", e); } return returnData; } /** * 獲取接口訪問憑證。將獲得的json結果轉爲Token對象 * @return */ public static Token getToken(){ Token token = null; String requestUrl = token_url; // 發起GET請求獲取憑證 JSONObject returnData = getTokenJsonObject(requestUrl, "GET", null); if(null != returnData){ try { token = new Token(); token.setAccessToken(returnData.getString("access_token")); token.setExpiresIn(Integer.parseInt(returnData.getString("expires_in"))); } catch (Exception e) { token = null; // 獲取token失敗 System.out.printf("獲取token失敗 errcode:{} errmsg:{}", returnData.get("errcode"), returnData.get("errmsg")); } } return token; } /** * 獲取jsapi_ticket * * @param appid 憑證 * @param appsecret 密鑰 * @return */ public static JsapiTicket getJsapiTicket(String accessToken) { //獲取公衆號jsapi_ticket的連接 String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?" + "access_token=ACCESS_TOKEN&type=jsapi"; //ticket分享值 JsapiTicket jsapiticket = null; if(accessToken != null){ String requestUrl = jsapi_ticket_url.replace("ACCESS_TOKEN", accessToken); JSONObject jsonObject = getTokenJsonObject(requestUrl, "GET", null); // 若是請求成功 if (null != jsonObject) { try { jsapiticket = new JsapiTicket(); jsapiticket.setTicket(jsonObject.getString("ticket")); jsapiticket.setExpiresIn(jsonObject.getInt("expires_in")); } catch (JSONException e) { jsapiticket = null; // 獲取ticket失敗 System.out.printf("獲取ticket失敗 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); } } }else{ System.out.println("*****token爲空 獲取ticket失敗******"); } return jsapiticket; } }
package com.runmin.bajie.util; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; public class MyX509TrustManager implements X509TrustManager { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }
package com.runmin.bajie.util; 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; /** * 官方給的使用js的驗證工具 * */ public class JsSignUtil { public static String accessToken = null; public static Map<String, String> sign(String url) { // 獲取accessToken accessToken = TokenUtil.getToken().getAccessToken(); // 獲取JsapiTicket String jsapi_ticket = TokenUtil.getJsapiTicket(accessToken).getTicket(); Map<String, String> ret = new HashMap<String, String>(); String nonce_str = create_nonce_str(); String timestamp = create_timestamp(); String string1; String signature = ""; // 注意這裏參數名必須所有小寫,且必須有序 string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "×tamp=" + timestamp + "&url=" + url;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", jsapi_ticket); ret.put("nonceStr", nonce_str); ret.put("timestamp", timestamp); ret.put("signature", signature); ret.put("appId", "wxd3bda909c7fb1467"); return ret; } /** * 隨機加密 * * @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; } /** * 產生隨機串--由程序本身隨機產生 * * @return */ private static String create_nonce_str() { return UUID.randomUUID().toString(); } /** * 由程序本身獲取當前時間 * * @return */ private static String create_timestamp() { return Long.toString(System.currentTimeMillis() / 1000); } }
package com.runmin.bajie.web; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.runmin.bajie.util.JsSignUtil; @Controller public class WeixinScanController { /** * 微信掃一掃接口的後臺處理程序 * * @param request * @param response * @return * @throws Exception */ @RequestMapping(value = "/weixinScan") @ResponseBody public Object weixinScan(HttpServletRequest request, HttpServletResponse response) throws Exception { String weburl = request.getParameter("url"); Map<String, String> resMap = new HashMap<String, String>(); resMap = JsSignUtil.sign(weburl); return resMap; } }