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; } }