package com.huaheng.api.WAYBILLNO.service; import com.huaheng.pc.config.KDCertification.domain.KDCertification; import com.huaheng.pc.config.KDCertification.service.KDCertificationService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.net.ssl.*; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.util.Map; import java.util.TreeMap; @Service public class KuaidiServiceImpl implements KuaidiService { @Resource private KDCertificationService kdCertificationService; private static String appKey = "dEalu7vYJMAA"; //昆山华恒焊接股份有限公司 private static String appSecret = "5447e797b54442778d12da773172d397"; static { try { SSLContext sslcontext = SSLContext.getInstance("SSL", "SunJSSE"); sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()}, new java.security.SecureRandom()); HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslsession) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier); HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory()); } catch (Exception e) { e.printStackTrace(); } } /** * 校验回调信息的sign * * @param callbackData 回调的参数数据 * @return 校验是否通过 */ @Override public boolean callbackVerify(Map<String, String> callbackData) { callbackData = transformToTreeMap(callbackData); StringBuilder sbd = new StringBuilder(appSecret); for (Map.Entry<String, String> entry : callbackData.entrySet()) { if (!"sign".equals(entry.getKey())) { sbd.append(entry.getKey()).append(entry.getKey()); } } sbd.append(appSecret); return new MD5().encode(sbd.toString()).equals(callbackData.get("sign")); } /** * 生成授权地址 * * @param state state * @return 授权地址 * @throws UnsupportedEncodingException */ @Override public String authorize(String state) throws Exception { KDCertification kdCertification = new KDCertification(); kdCertification = kdCertificationService.getOne(kdCertification); String timestamp = String.valueOf(System.currentTimeMillis()); state = null == state ? "" : state; Map<String, String> data = new TreeMap<>(); data.put("client_id", appKey); data.put("response_type", "code"); data.put("redirect_uri", kdCertification.getRedirectUrl()); data.put("state", state); data.put("timestamp", timestamp); String sign = generateSignByClass(data, kdCertification.getAppSecret()); return "https://b.kuaidi100.com/open/oauth/authorize?response_type=code&client_id=" + appKey + "&redirect_uri=" + URLEncoder.encode(kdCertification.getRedirectUrl(), "UTF-8") + "&state=" + state + "×tamp=" + timestamp + "&sign=" + sign; } /** * 获取登录 * * @param state * @param appkeys * @param appsecrets * @return * @throws Exception */ public static String authorizeByClass(String state, String appkeys, String appsecrets) throws Exception { // KDCertification kdCertification = new KDCertification(); // LambdaQueryWrapper<KDCertification> wrapper = Wrappers.lambdaQuery(); // wrapper.eq(KDCertification::getWarehouseCode, warehouseCode); // kdCertification = kdCertificationService.getOne(kdCertification); String redirectUrl = "http://222.92.108.42:443/wms/api/kuaidi/test"; String timestamp = String.valueOf(System.currentTimeMillis()); state = null == state ? "" : state; Map<String, String> data = new TreeMap<>(); data.put("client_id", appkeys); data.put("response_type", "code"); data.put("redirect_uri", redirectUrl); data.put("state", state); data.put("timestamp", timestamp); String sign = generateSignByClass(data, appsecrets); return "https://b.kuaidi100.com/open/oauth/authorize?response_type=code&client_id=" + appkeys + "&redirect_uri=" + URLEncoder.encode(redirectUrl, "UTF-8") + "&state=" + state + "×tamp=" + timestamp + "&sign=" + sign; } /** * 用授权得到的code换取accessToken * 废弃接口 * * @param code 临时凭证 * @return */ @Override public String accessToken(String code) throws Exception { KDCertification kdCertification = new KDCertification(); kdCertification = kdCertificationService.getOne(kdCertification); if (null == code || code.length() < 1) { throw new RuntimeException("无效参数"); } String timestamp = String.valueOf(System.currentTimeMillis()); Map<String, String> data = new TreeMap<>(); data.put("client_id", appKey); data.put("client_secret", appSecret); data.put("grant_type", "authorization_code"); data.put("code", code); data.put("redirect_uri", kdCertification.getRedirectUrl()); data.put("timestamp", timestamp); data.put("sign", generateSign(data)); return httpsRequest("https://b.kuaidi100.com/open/oauth/accessToken", data); } public static String accessTokenByClass(String code, String appKeys, String appSecrets) throws Exception { if (null == code || code.length() < 1) { throw new RuntimeException("无效参数"); } String redirectUrl = "http://222.92.108.42:443/wms/api/kuaidi/test"; String timestamp = String.valueOf(System.currentTimeMillis()); Map<String, String> data = new TreeMap<>(); data.put("client_id", appKeys); data.put("client_secret", appSecrets); data.put("grant_type", "authorization_code"); data.put("code", code); data.put("redirect_uri", redirectUrl); data.put("timestamp", timestamp); data.put("sign", generateSignByClass(data, appSecrets)); return httpsRequestStatic("https://b.kuaidi100.com/open/oauth/accessToken", data); } /** * 刷新accessToken * * @param refreshToken 刷新token * @return */ @Override public String refreshToken(String refreshToken) throws Exception { if (null == refreshToken || refreshToken.length() < 1) { throw new RuntimeException("无效参数"); } String timestamp = String.valueOf(System.currentTimeMillis()); Map<String, String> data = new TreeMap<>(); data.put("client_id", appKey); data.put("client_secret", appSecret); data.put("grant_type", "refresh_token"); data.put("refresh_token", refreshToken); data.put("timestamp", timestamp); data.put("sign", generateSign(data)); return httpsRequest("https://b.kuaidi100.com/open/oauth/refreshToken", data); } /** * 刷新accessToken * * @param kdCertification 刷新token * @return */ @Override public String refreshTokenByClass(KDCertification kdCertification) throws Exception { if (null == kdCertification.getRefreshToken() || kdCertification.getRefreshToken().length() < 1) { throw new RuntimeException("无效参数"); } String timestamp = String.valueOf(System.currentTimeMillis()); Map<String, String> data = new TreeMap<>(); data.put("client_id", kdCertification.getAppKey()); data.put("client_secret", kdCertification.getAppSecret()); data.put("grant_type", "refresh_token"); data.put("refresh_token", kdCertification.getRefreshToken()); data.put("timestamp", timestamp); data.put("sign", generateSignByClass(data, kdCertification.getAppSecret())); System.out.println(data); return httpsRequest("https://b.kuaidi100.com/open/oauth/refreshToken", data); } /** * 导入订单 * * @param accessToken 身份凭证 * @param orderData 订单信息 * @return */ @Override public String send(String accessToken, String orderData) throws Exception { if (null == accessToken || accessToken.length() < 1 || null == orderData || orderData.length() < 1) { throw new RuntimeException("无效参数"); } String timestamp = String.valueOf(System.currentTimeMillis()); Map<String, String> data = new TreeMap<>(); data.put("appid", appKey); data.put("access_token", accessToken); data.put("data", orderData); data.put("timestamp", timestamp); data.put("sign", generateSign(data)); return httpsRequest("https://b.kuaidi100.com/v6/open/api/send", data); } /** * 修改订单 * * @param accessToken 身份凭证 * @param orderData 订单信息 * @return */ @Override public String update(String accessToken, String orderData) throws Exception { if (null == accessToken || accessToken.length() < 1 || null == orderData || orderData.length() < 1) { throw new RuntimeException("无效参数"); } String timestamp = String.valueOf(System.currentTimeMillis()); Map<String, String> data = new TreeMap<>(); data.put("appid", appKey); data.put("access_token", accessToken); data.put("data", orderData); data.put("timestamp", timestamp); data.put("sign", generateSign(data)); return httpsRequest("https://b.kuaidi100.com/v6/open/api/update", data); } /** * 快速打印 * * @param accessToken 身份凭证 * @param printList 订单号列表 * @return 打印订单的地址 */ @Override public String quickPrint(String accessToken, String printList) { if (null == accessToken || accessToken.length() < 1 || null == printList || printList.length() < 1) { throw new RuntimeException("无效参数"); } String timestamp = String.valueOf(System.currentTimeMillis()); Map<String, String> data = new TreeMap<>(); data.put("appid", appKey); data.put("access_token", accessToken); data.put("printlist", printList); data.put("timestamp", timestamp); String sign = generateSign(data); return "https://b.kuaidi100.com/v6/open/api/print?appid=" + appKey + "&access_token=" + accessToken + "&printlist=" + printList + "×tamp=" + timestamp + "&sign=" + sign; } /** * 自动打印 * * @param accessToken 身份凭证 * @param printList 订单号列表 * @return */ @Override public String autoPrint(String accessToken, String printList) throws Exception { String timestamp = String.valueOf(System.currentTimeMillis()); Map<String, String> data = new TreeMap<>(); data.put("appid", appKey); data.put("access_token", accessToken); data.put("printlist", printList); data.put("timestamp", timestamp); data.put("sign", generateSign(data)); return httpsRequest("https://b.kuaidi100.com/v6/open/api/autoPrint", data); } /** * 生成签名 * * @param data 请求数据 * @return 签名 */ private static String generateSign(Map<String, String> data) { data = transformToTreeMap(data); StringBuilder sbd = new StringBuilder(appSecret); for (Map.Entry<String, String> entry : data.entrySet()) { sbd.append(entry.getKey()).append(entry.getValue()); } sbd.append(appSecret); return new MD5().encode(sbd.toString()); } /** * 生成签名 * * @param data 请求数据 * @return 签名 */ private static String generateSignByClass(Map<String, String> data, String appSecrets) { data = transformToTreeMap(data); StringBuilder sbd = new StringBuilder(appSecrets); for (Map.Entry<String, String> entry : data.entrySet()) { sbd.append(entry.getKey()).append(entry.getValue()); } sbd.append(appSecrets); return new MD5().encode(sbd.toString()); } public static void main(String[] args) throws Exception { // String redirectUrl = "http://222.92.108.42:443/wms/api/kuaidi/test"; // String timestamp = String.valueOf(System.currentTimeMillis()); // String state = ""; // Map<String, String> data = new TreeMap<>(); // data.put("client_id", "wKa32LXi8F9t"); // data.put("response_type", "code"); // data.put("redirect_uri", redirectUrl); // data.put("state", state); // data.put("timestamp", timestamp); // String sign = generateSignByClass(data, "918dc02a3348480380f607da0bb75c2b"); // System.out.println(timestamp); // System.out.println(sign); String appkey = "wKa32LXi8F9t"; String appscrets = "918dc02a3348480380f607da0bb75c2b"; // String str = authorizeByClass("", appkey, appscrets); // System.out.println(str); String str1 = accessTokenByClass("lhzANxEd", appkey, appscrets); System.out.println(str1); } /** * 把map转换为treeMap * * @param map 任意类型的map * @return treeMap */ private static Map<String, String> transformToTreeMap(Map<String, String> map) { return map instanceof TreeMap ? map : new TreeMap<>(map); } /** * 发送http请求 * * @param url 请求地址 * @param data 请求参数 * @return 接口返回的结果 */ private String httpsRequest(String url, Map<String, String> data) throws Exception { URL apiUrl = new URL(url); StringBuilder sbd = new StringBuilder(); StringBuilder paramSbd = new StringBuilder(); if (null != data) { for (Map.Entry<String, String> entry : data.entrySet()) { paramSbd.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); } } String param = paramSbd.length() > 0 ? paramSbd.substring(0, paramSbd.length() - 1) : ""; try { HttpURLConnection httpConn = (HttpURLConnection) apiUrl.openConnection(); //设置参数 httpConn.setDoOutput(true); httpConn.setDoInput(true); httpConn.setUseCaches(false); httpConn.setRequestMethod("POST"); //设置请求属性 httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); httpConn.setRequestProperty("Charset", "UTF-8"); httpConn.setRequestProperty("Accept", "application/json;charset=UTF-8"); //建立输入流,向指向的URL传入参数 OutputStream out = httpConn.getOutputStream(); out.write(param.getBytes("UTF-8")); out.flush(); out.close(); //获得响应状态 int resultCode = httpConn.getResponseCode(); if (HttpURLConnection.HTTP_OK == resultCode) { String readLine; BufferedReader responseReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "UTF-8")); while ((readLine = responseReader.readLine()) != null) { sbd.append(readLine).append("\n"); } responseReader.close(); System.out.println(sbd.toString()); } else { throw new RuntimeException("http请求失败:" + httpConn.getResponseCode()); } } catch (Exception e) { throw new RuntimeException("http请求失败", e); } return sbd.toString(); } /** * 发送http请求 * * @param url 请求地址 * @param data 请求参数 * @return 接口返回的结果 */ private static String httpsRequestStatic(String url, Map<String, String> data) throws Exception { URL apiUrl = new URL(url); StringBuilder sbd = new StringBuilder(); StringBuilder paramSbd = new StringBuilder(); if (null != data) { for (Map.Entry<String, String> entry : data.entrySet()) { paramSbd.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); } } String param = paramSbd.length() > 0 ? paramSbd.substring(0, paramSbd.length() - 1) : ""; try { HttpURLConnection httpConn = (HttpURLConnection) apiUrl.openConnection(); //设置参数 httpConn.setDoOutput(true); httpConn.setDoInput(true); httpConn.setUseCaches(false); httpConn.setRequestMethod("POST"); //设置请求属性 httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); httpConn.setRequestProperty("Charset", "UTF-8"); httpConn.setRequestProperty("Accept", "application/json;charset=UTF-8"); //建立输入流,向指向的URL传入参数 OutputStream out = httpConn.getOutputStream(); out.write(param.getBytes("UTF-8")); out.flush(); out.close(); //获得响应状态 int resultCode = httpConn.getResponseCode(); if (HttpURLConnection.HTTP_OK == resultCode) { String readLine; BufferedReader responseReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "UTF-8")); while ((readLine = responseReader.readLine()) != null) { sbd.append(readLine).append("\n"); } responseReader.close(); System.out.println(sbd.toString()); } else { throw new RuntimeException("http请求失败:" + httpConn.getResponseCode()); } } catch (Exception e) { throw new RuntimeException("http请求失败", e); } return sbd.toString(); } static class MD5 { // 获得MD5摘要算法的 MessageDigest 对象 private MessageDigest _mdInst = null; private char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; private MessageDigest getMdInst() { if (_mdInst == null) { try { _mdInst = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } return _mdInst; } String encode(String s) { try { byte[] btInput = s.getBytes("UTF-8"); // 使用指定的字节更新摘要 getMdInst().update(btInput); // 获得密文 byte[] md = getMdInst().digest(); // 把密文转换成十六进制的字符串形式 int j = md.length; char str[] = new char[j * 2]; int k = 0; for (byte byte0 : md) { str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (Exception e) { e.printStackTrace(); return null; } } } static class MyX509TrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate certificates[], String authType) { } @Override public void checkServerTrusted(X509Certificate[] ax509certificate, String s) { } @Override public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub return null; } } }