From f85f78696659f57dc2c812bd40e244624eb9eedb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=9E=97?= Date: Wed, 4 Sep 2019 17:07:57 +0800 Subject: [PATCH] xiufu --- build.gradle | 35 ++- gradle/wrapper/gradle-wrapper.jar | Bin 56177 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- settings.gradle | 3 +- src/main/java/com/zl/aliyun/iot/IotApi.java | 71 ----- .../com/zl/aliyun/iot/SignatureUtils.java | 100 ------- src/main/java/com/zl/aliyun/iot/UrlUtil.java | 50 ---- .../java/com/zl/aliyun/nls/CreateToekn.java | 244 ---------------- src/main/java/com/zl/aliyun/nls/NlsToken.java | 52 ---- .../com/zl/aliyun/nls/NlsTokenResponse.java | 52 ---- .../java/com/zl/aliyun/nls/TokenListener.java | 25 -- .../java/com/zl/aliyun/nls/TokenUtil.java | 150 ---------- .../com/zl/aliyun/util/Base64Encoder.java | 76 ----- .../java/com/zl/aliyun/util/DateUtil.java | 30 -- .../java/com/zl/aliyun/util/JsonUtil.java | 59 ---- .../java/com/zl/aliyun/util/SignUtil.java | 70 ----- .../java/com/zl/aliyun/util/StringUtil.java | 234 ---------------- src/main/java/com/zl/aliyun/util/UrlUtil.java | 59 ---- .../zl/aliyun/util/http/ByteContentFile.java | 55 ---- .../zl/aliyun/util/http/FileContentFile.java | 59 ---- .../com/zl/aliyun/util/http/HttpCallBack.java | 25 -- .../com/zl/aliyun/util/http/HttpUtil.java | 261 ------------------ src/test/java/com/zl/demo/nls/NLSDemo.java | 49 ---- 23 files changed, 25 insertions(+), 1738 deletions(-) delete mode 100644 src/main/java/com/zl/aliyun/iot/IotApi.java delete mode 100644 src/main/java/com/zl/aliyun/iot/SignatureUtils.java delete mode 100644 src/main/java/com/zl/aliyun/iot/UrlUtil.java delete mode 100644 src/main/java/com/zl/aliyun/nls/CreateToekn.java delete mode 100644 src/main/java/com/zl/aliyun/nls/NlsToken.java delete mode 100644 src/main/java/com/zl/aliyun/nls/NlsTokenResponse.java delete mode 100644 src/main/java/com/zl/aliyun/nls/TokenListener.java delete mode 100644 src/main/java/com/zl/aliyun/nls/TokenUtil.java delete mode 100644 src/main/java/com/zl/aliyun/util/Base64Encoder.java delete mode 100644 src/main/java/com/zl/aliyun/util/DateUtil.java delete mode 100644 src/main/java/com/zl/aliyun/util/JsonUtil.java delete mode 100644 src/main/java/com/zl/aliyun/util/SignUtil.java delete mode 100644 src/main/java/com/zl/aliyun/util/StringUtil.java delete mode 100644 src/main/java/com/zl/aliyun/util/UrlUtil.java delete mode 100644 src/main/java/com/zl/aliyun/util/http/ByteContentFile.java delete mode 100644 src/main/java/com/zl/aliyun/util/http/FileContentFile.java delete mode 100644 src/main/java/com/zl/aliyun/util/http/HttpCallBack.java delete mode 100644 src/main/java/com/zl/aliyun/util/http/HttpUtil.java delete mode 100644 src/test/java/com/zl/demo/nls/NLSDemo.java diff --git a/build.gradle b/build.gradle index 20a3b60..89864c5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,19 +1,28 @@ -plugins { - id 'java' -} +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + google() + jcenter() -group 'com.zl' -version '1.0-SNAPSHOT' + } + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} -sourceCompatibility = 1.8 +allprojects { + repositories { + google() + jcenter() -repositories { - mavenCentral() + } } -dependencies { - compile group: 'commons-codec', name: 'commons-codec', version: '1.13' - compile group: 'com.alibaba', name: 'fastjson', version: '1.2.59' - compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.14.2' - testCompile group: 'junit', name: 'junit', version: '4.12' +task clean(type: Delete) { + delete rootProject.buildDir } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 94336fcae912db8a11d55634156fa011f4686124..f6b961fd5a86aa5fbfe90f707c3138408be7c718 100644 GIT binary patch delta 47652 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 - * @Version 1.0 - * @Description TODO - * @date 2019/09/02 17:40 - */ -public class IotApi { - // AccessKey 信息 - public static String accessKey = "1234567890123456"; - public static String accessKeySecret = "123456789012345678901234567890"; - - public final static String CHARSET_UTF8 = "utf8"; - - /** - * @param args - * @throws UnsupportedEncodingException - * @1. 需求修改Config.java中的AccessKey信息 - * @2. 建议使用方法二,所有参数都需要一一填写 - * @3. "最终signature"才是你需要的签名最终结果 - */ - public static void main(String[] args) throws UnsupportedEncodingException { - - // 方法一 - System.out.println("方法一:"); - String str = "GET&%2F&AccessKeyId%3D" + accessKey - + "%26Action%3DRegisterDevice%26DeviceName%3D1533023037%26Format%3DJSON%26ProductKey%3DaxxxUtgaRLB%26RegionId%3Dcn-shanghai%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3D1533023037%26SignatureVersion%3D1" - + ".0%26Timestamp%3D2018-07-31T07%253A43%253A57Z%26Version%3D2018-01-20"; - byte[] signBytes; - try { - signBytes = SignatureUtils.hmacSHA1Signature(accessKeySecret + "&", str.toString()); - String signature = SignatureUtils.newStringByBase64(signBytes); - System.out.println("signString---" + str); - System.out.println("signature----" + signature); - System.out.println("最终signature:" + URLEncoder.encode(signature, CHARSET_UTF8)); - } catch (Exception e) { - e.printStackTrace(); - } - System.out.println(); - - // 方法二 - System.out.println("方法二:"); - Map map = new HashMap(); - // 公共参数 - map.put("Format", "JSON"); - map.put("Version", "2018-01-20"); - map.put("AccessKeyId", accessKey); - map.put("SignatureMethod", "HMAC-SHA1"); - map.put("Timestamp", "2018-07-31T07:43:57Z"); - map.put("SignatureVersion", "1.0"); - map.put("SignatureNonce", "1533023037"); - map.put("RegionId", "cn-shanghai"); - // 请求参数 - map.put("Action", "RegisterDevice"); - map.put("DeviceName", "1533023037"); - map.put("ProductKey", "axxxUtgaRLB"); - try { - String signature = SignatureUtils.generate("GET", map, accessKeySecret); - System.out.println("最终signature:" + signature); - } catch (Exception e) { - e.printStackTrace(); - } - System.out.println(); - } -} diff --git a/src/main/java/com/zl/aliyun/iot/SignatureUtils.java b/src/main/java/com/zl/aliyun/iot/SignatureUtils.java deleted file mode 100644 index ee29c15..0000000 --- a/src/main/java/com/zl/aliyun/iot/SignatureUtils.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.zl.aliyun.iot; - -import com.zl.aliyun.util.StringUtil; -import org.apache.commons.codec.binary.Base64; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.Map; -import java.util.TreeMap; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/02 17:40 - */ -public class SignatureUtils { - private final static String CHARSET_UTF8 = "utf8"; - private final static String ALGORITHM = "UTF-8"; - private final static String SEPARATOR = "&"; - - public static Map splitQueryString(String url) - throws URISyntaxException, UnsupportedEncodingException { - URI uri = new URI(url); - String query = uri.getQuery(); - final String[] pairs = query.split("&"); - TreeMap queryMap = new TreeMap(); - for (String pair : pairs) { - final int idx = pair.indexOf("="); - final String key = idx > 0 ? pair.substring(0, idx) : pair; - if (!queryMap.containsKey(key)) { - queryMap.put(key, URLDecoder.decode(pair.substring(idx + 1), CHARSET_UTF8)); - } - } - return queryMap; - } - - public static String generate(String method, Map parameter, String accessKeySecret) - throws Exception { - String signString = generateSignString(method, parameter); - System.out.println("signString---" + signString); - byte[] signBytes = hmacSHA1Signature(accessKeySecret + "&", signString); - String signature = newStringByBase64(signBytes); - System.out.println("signature----" + signature); - if ("POST".equals(method)) { - return signature; - } - return URLEncoder.encode(signature, "UTF-8"); - } - - public static String generateSignString(String httpMethod, Map parameter) throws IOException { - TreeMap sortParameter = new TreeMap(); - sortParameter.putAll(parameter); - String canonicalizedQueryString = UrlUtil.generateQueryString(sortParameter, true); - if (null == httpMethod) { - throw new RuntimeException("httpMethod can not be empty"); - } - StringBuilder stringToSign = new StringBuilder(); - stringToSign.append(httpMethod).append(SEPARATOR); - stringToSign.append(percentEncode("/")).append(SEPARATOR); - stringToSign.append(percentEncode(canonicalizedQueryString)); - return stringToSign.toString(); - } - - public static String percentEncode(String value) { - try { - return value == null ? null - : URLEncoder.encode(value, CHARSET_UTF8).replace("+", "%20").replace("*", "%2A").replace("%7E", - "~"); - } catch (Exception e) { - } - return ""; - } - - public static byte[] hmacSHA1Signature(String secret, String baseString) throws Exception { - if (StringUtil.isEmpty(secret)) { - throw new IOException("secret can not be empty"); - } - if (StringUtil.isEmpty(baseString)) { - return null; - } - Mac mac = Mac.getInstance("HmacSHA1"); - SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(CHARSET_UTF8), ALGORITHM); - mac.init(keySpec); - return mac.doFinal(baseString.getBytes(CHARSET_UTF8)); - } - - public static String newStringByBase64(byte[] bytes) throws UnsupportedEncodingException { - if (bytes == null || bytes.length == 0) { - return null; - } - return new String(Base64.encodeBase64(bytes, false), CHARSET_UTF8); - } -} diff --git a/src/main/java/com/zl/aliyun/iot/UrlUtil.java b/src/main/java/com/zl/aliyun/iot/UrlUtil.java deleted file mode 100644 index 3721b54..0000000 --- a/src/main/java/com/zl/aliyun/iot/UrlUtil.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.zl.aliyun.iot; - -import com.zl.aliyun.util.StringUtil; - -import java.net.URLEncoder; -import java.util.Map; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/02 17:43 - */ -public class UrlUtil { - private final static String CHARSET_UTF8 = "utf8"; - - public static String urlEncode(String url) { - if (!StringUtil.isEmpty(url)) { - try { - url = URLEncoder.encode(url, "UTF-8"); - } catch (Exception e) { - System.out.println("Url encode error:" + e.getMessage()); - } - } - return url; - } - - public static String generateQueryString(Map params, boolean isEncodeKV) { - StringBuilder canonicalizedQueryString = new StringBuilder(); - for (Map.Entry entry : params.entrySet()) { - if (isEncodeKV) { - canonicalizedQueryString.append(percentEncode(entry.getKey())).append("=") - .append(percentEncode(entry.getValue())).append("&"); - } else { canonicalizedQueryString.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); } - } - if (canonicalizedQueryString.length() > 1) { - canonicalizedQueryString.setLength(canonicalizedQueryString.length() - 1); - } - return canonicalizedQueryString.toString(); - } - - public static String percentEncode(String value) { - try { - return value == null ? null : URLEncoder.encode(value, CHARSET_UTF8).replace("+", "%20").replace("*", "%2A").replace("%7E", "~"); - } catch (Exception e) { - - } - return ""; - } -} diff --git a/src/main/java/com/zl/aliyun/nls/CreateToekn.java b/src/main/java/com/zl/aliyun/nls/CreateToekn.java deleted file mode 100644 index 535c9a5..0000000 --- a/src/main/java/com/zl/aliyun/nls/CreateToekn.java +++ /dev/null @@ -1,244 +0,0 @@ -package com.zl.aliyun.nls; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.zl.aliyun.util.Base64Encoder; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.text.SimpleDateFormat; -import java.util.*; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/02 17:38 - */ -public class CreateToekn { - private final static String TIME_ZONE = "GMT"; - private final static String FORMAT_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss'Z'"; - private final static String URL_ENCODING = "UTF-8"; - private static final String ALGORITHM_NAME = "HmacSHA1"; - private static final String ENCODING = "UTF-8"; - private static String token = null; - private static long expireTime = 0; - - /** - * 获取时间戳 - * 必须符合ISO8601规范,并需要使用UTC时间,时区为+0 - */ - public static String getISO8601Time(Date date) { - Date nowDate = date; - if (null == date) { - nowDate = new Date(); - } - SimpleDateFormat df = new SimpleDateFormat(FORMAT_ISO8601); - df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE)); - return df.format(nowDate); - } - - /** - * 获取UUID - */ - public static String getUniqueNonce() { - UUID uuid = UUID.randomUUID(); - return uuid.toString(); - } - - /** - * URL编码 - * 使用UTF-8字符集按照 RFC3986 规则编码请求参数和参数取值 - */ - public static String percentEncode(String value) throws UnsupportedEncodingException { - return value != null ? URLEncoder.encode(value, URL_ENCODING).replace("+", "%20") - .replace("*", "%2A").replace("%7E", "~") : null; - } - - /*** - * 将参数排序后,进行规范化设置,组合成请求字符串 - * @param queryParamsMap 所有请求参数 - * @return 规范化的请求字符串 - */ - public static String canonicalizedQuery(Map queryParamsMap) { - String[] sortedKeys = queryParamsMap.keySet().toArray(new String[]{}); - Arrays.sort(sortedKeys); - String queryString = null; - try { - StringBuilder canonicalizedQueryString = new StringBuilder(); - for (String key : sortedKeys) { - canonicalizedQueryString.append("&") - .append(percentEncode(key)).append("=") - .append(percentEncode(queryParamsMap.get(key))); - } - queryString = canonicalizedQueryString.toString().substring(1); - System.out.println("规范化后的请求参数串:" + queryString); - } catch (UnsupportedEncodingException e) { - System.out.println("UTF-8 encoding is not supported."); - e.printStackTrace(); - } - return queryString; - } - - /*** - * 构造签名字符串 - * @param method HTTP请求的方法 - * @param urlPath HTTP请求的资源路径 - * @param queryString 规范化的请求字符串 - * @return 签名字符串 - */ - public static String createStringToSign(String method, String urlPath, String queryString) { - String stringToSign = null; - try { - StringBuilder strBuilderSign = new StringBuilder(); - strBuilderSign.append(method); - strBuilderSign.append("&"); - strBuilderSign.append(percentEncode(urlPath)); - strBuilderSign.append("&"); - strBuilderSign.append(percentEncode(queryString)); - stringToSign = strBuilderSign.toString(); - System.out.println("构造的签名字符串:" + stringToSign); - } catch (UnsupportedEncodingException e) { - System.out.println("UTF-8 encoding is not supported."); - e.printStackTrace(); - } - return stringToSign; - } - - /*** - * 计算签名 - * @param stringToSign 签名字符串 - * @param accessKeySecret 阿里云AccessKey Secret加上与号& - * @return 计算得到的签名 - */ - public static String sign(String stringToSign, String accessKeySecret) { - try { - Mac mac = Mac.getInstance(ALGORITHM_NAME); - mac.init(new SecretKeySpec( - accessKeySecret.getBytes(ENCODING), - ALGORITHM_NAME - )); - byte[] signData = mac.doFinal(stringToSign.getBytes(ENCODING)); - // String signBase64 = DatatypeConverter.printBase64Binary(signData); - // String signBase64= Base64.getEncoder().encodeToString(signData); - // String signBase64= android.util.Base64.encodeToString(signData, Base64.CRLF); - String signBase64= Base64Encoder.encode(signData); - System.out.println("计算的得到的签名:" + signBase64); - String signUrlEncode = percentEncode(signBase64); - System.out.println("UrlEncode编码后的签名:" + signUrlEncode); - return signUrlEncode; - } catch (NoSuchAlgorithmException e) { - throw new IllegalArgumentException(e.toString()); - } catch (UnsupportedEncodingException e) { - throw new IllegalArgumentException(e.toString()); - } catch (InvalidKeyException e) { - throw new IllegalArgumentException(e.toString()); - } - } - - /*** - * 发送HTTP GET请求,获取token和有效期时间戳 - * @param queryString 请求参数 - */ - public static void processGETRequest(String queryString) { - /** - * 设置HTTP GET请求 - * 1. 使用HTTP协议 - * 2. Token服务域名:nls-meta.cn-shanghai.aliyuncs.com - * 3. 请求路径:/ - * 4. 设置请求参数 - */ - String url = "http://nls-meta.cn-shanghai.aliyuncs.com"; - url = url + "/"; - url = url + "?" + queryString; - System.out.println("HTTP请求链接:" + url); - Request request = new Request.Builder() - .url(url) - .header("Accept", "application/json") - .get() - .build(); - try { - OkHttpClient client = new OkHttpClient(); - Response response = client.newCall(request).execute(); - String result = response.body().string(); - if (response.isSuccessful()) { - JSONObject rootObj = JSON.parseObject(result); - JSONObject tokenObj = rootObj.getJSONObject("Token"); - if (tokenObj != null) { - token = tokenObj.getString("Id"); - expireTime = tokenObj.getLongValue("ExpireTime"); - } else { - System.err.println("提交获取Token请求失败: " + result); - } - } else { - System.err.println("提交获取Token请求失败: " + result); - } - response.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void getToken(String accessKeyId, String accessKeySecret) { - System.out.println(getISO8601Time(null)); - // 所有请求参数 - Map queryParamsMap = new HashMap<>(); - queryParamsMap.put("AccessKeyId", accessKeyId); - queryParamsMap.put("Action", "CreateToken"); - queryParamsMap.put("Version", "2019-02-28"); - queryParamsMap.put("Timestamp", getISO8601Time(null)); - queryParamsMap.put("Format", "JSON"); - queryParamsMap.put("RegionId", "cn-shanghai"); - queryParamsMap.put("SignatureMethod", "HMAC-SHA1"); - queryParamsMap.put("SignatureVersion", "1.0"); - queryParamsMap.put("SignatureNonce", getUniqueNonce()); - /** - * 1.构造规范化的请求字符串 - */ - String queryString = canonicalizedQuery(queryParamsMap); - if (null == queryString) { - System.out.println("构造规范化的请求字符串失败!"); - return; - } - /** - * 2.构造签名字符串 - */ - String method = "GET"; // 发送请求的 HTTP 方法,GET - String urlPath = "/"; // 请求路径 - String stringToSign = createStringToSign(method, urlPath, queryString); - if (null == stringToSign) { - System.out.println("构造签名字符串失败"); - return; - } - /** - * 3.计算签名 - */ - String signature = sign(stringToSign, accessKeySecret + "&"); - if (null == signature) { - System.out.println("计算签名失败!"); - return; - } - /** - * 4.将签名加入到第1步获取的请求字符串 - */ - String queryStringWithSign = "Signature=" + signature + "&" + queryString; - System.out.println("带有签名的请求字符串:" + queryStringWithSign); - /** - * 5.发送HTTP GET请求,获取token - */ - processGETRequest(queryStringWithSign); - if (token != null) { - System.out.println("获取的Token:" + token + ", 有效期时间戳(秒):" + expireTime); - // 将10位数的时间戳转换为北京时间 - String expireDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(expireTime * 1000)); - System.out.println("Token有效期的北京时间:" + expireDate); - } - } -} diff --git a/src/main/java/com/zl/aliyun/nls/NlsToken.java b/src/main/java/com/zl/aliyun/nls/NlsToken.java deleted file mode 100644 index 22d1adb..0000000 --- a/src/main/java/com/zl/aliyun/nls/NlsToken.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.zl.aliyun.nls; - -import java.io.Serializable; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/03 16:19 - */ -public class NlsToken implements Serializable { - private static final long serialVersionUID = -841117051816861042L; - private long ExpireTime; - private String Id; - private String UserId; - - public NlsToken() { - } - - public long getExpireTime() { - return ExpireTime; - } - - public void setExpireTime(long expireTime) { - ExpireTime = expireTime; - } - - public String getId() { - return Id; - } - - public void setId(String id) { - Id = id; - } - - public String getUserId() { - return UserId; - } - - public void setUserId(String userId) { - UserId = userId; - } - - @Override - public String toString() { - return "NlsToken{" + - "ExpireTime=" + ExpireTime + - ", Id='" + Id + '\'' + - ", UserId='" + UserId + '\'' + - '}'; - } -} diff --git a/src/main/java/com/zl/aliyun/nls/NlsTokenResponse.java b/src/main/java/com/zl/aliyun/nls/NlsTokenResponse.java deleted file mode 100644 index d92532b..0000000 --- a/src/main/java/com/zl/aliyun/nls/NlsTokenResponse.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.zl.aliyun.nls; - -import java.io.Serializable; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/03 16:18 - */ -public class NlsTokenResponse implements Serializable { - private static final long serialVersionUID = 4564566096568781967L; - private String NlsRequestId; - private String RequestId; - private NlsToken Token; - - public NlsTokenResponse() { - } - - public String getNlsRequestId() { - return NlsRequestId; - } - - public void setNlsRequestId(String nlsRequestId) { - NlsRequestId = nlsRequestId; - } - - public String getRequestId() { - return RequestId; - } - - public void setRequestId(String requestId) { - RequestId = requestId; - } - - public NlsToken getToken() { - return Token; - } - - public void setToken(NlsToken token) { - Token = token; - } - - @Override - public String toString() { - return "NlsTokenResponse{" + - "NlsRequestId='" + NlsRequestId + '\'' + - ", RequestId='" + RequestId + '\'' + - ", Token=" + Token + - '}'; - } -} diff --git a/src/main/java/com/zl/aliyun/nls/TokenListener.java b/src/main/java/com/zl/aliyun/nls/TokenListener.java deleted file mode 100644 index 63cc310..0000000 --- a/src/main/java/com/zl/aliyun/nls/TokenListener.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.zl.aliyun.nls; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/04 16:18 - */ -public interface TokenListener { - /** - * 获取token成功 - * - * @param token - * @return - */ - void onSuccess(String token); - - /** - * 获取token失败 - * - * @param e - * @return - */ - void onError(Exception e); -} diff --git a/src/main/java/com/zl/aliyun/nls/TokenUtil.java b/src/main/java/com/zl/aliyun/nls/TokenUtil.java deleted file mode 100644 index 6892fd1..0000000 --- a/src/main/java/com/zl/aliyun/nls/TokenUtil.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.zl.aliyun.nls; - -import com.alibaba.fastjson.TypeReference; -import com.zl.aliyun.util.DateUtil; -import com.zl.aliyun.util.SignUtil; -import com.zl.aliyun.util.StringUtil; -import com.zl.aliyun.util.UrlUtil; -import com.zl.aliyun.util.http.HttpCallBack; -import com.zl.aliyun.util.http.HttpUtil; - -import java.lang.ref.WeakReference; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/03 10:47 - */ -public class TokenUtil { - private static final String BASE_URL = "http://nls-meta.cn-shanghai.aliyuncs.com"; - private static TokenUtil INSTANCE; - private static WeakReference tokenReference; - - public TokenUtil() { - } - - public static String getToken(String accessKeyId, String accessKeySecret) { - String token = getMemberToken(); - if (StringUtil.isEmpty(token)) { - String queryString = generateTokenQuery(accessKeyId, accessKeySecret); - NlsToken nlsToken = synQueryToken(queryString); - if (nlsToken != null && !StringUtil.isEmpty(nlsToken.getId())) { - return nlsToken.getId(); - } else { - return null; - } - } else { - return token; - } - } - - public static void getToken(String accessKeyId, String accessKeySecret, TokenListener tokenListener) { - String token = getMemberToken(); - if (StringUtil.isEmpty(token)) { - String queryString = generateTokenQuery(accessKeyId, accessKeySecret); - aynQueryToken(queryString, tokenListener); - } else { - if (tokenListener != null) { - tokenListener.onSuccess(token); - } - } - } - - private static String getMemberToken() { - if (null == tokenReference) {return null;} - NlsToken nlsToken = tokenReference.get(); - if (null == nlsToken || StringUtil.isEmpty(nlsToken.getId())) {return null;} - Date tokenDate = new Date(nlsToken.getExpireTime() * 1000); - Date nowDate = new Date(System.currentTimeMillis()); - if (tokenDate.after(nowDate)) { - return nlsToken.getId(); - } else { - return null; - } - } - - private static void saveToken(NlsToken nlsToken) { - if (nlsToken != null) { - tokenReference = new WeakReference<>(nlsToken); - } - } - - public static String generateTokenQuery(String accessKeyId, String accessKeySecret) { - Map queryParamsMap = new HashMap<>(); - queryParamsMap.put("AccessKeyId", accessKeyId); - queryParamsMap.put("Action", "CreateToken"); - queryParamsMap.put("Version", "2019-02-28"); - queryParamsMap.put("Timestamp", DateUtil.getISO8601Time(null)); - queryParamsMap.put("Format", "JSON"); - queryParamsMap.put("RegionId", "cn-shanghai"); - queryParamsMap.put("SignatureMethod", "HMAC-SHA1"); - queryParamsMap.put("SignatureVersion", "1.0"); - queryParamsMap.put("SignatureNonce", SignUtil.getUniqueNonce()); - String queryString = UrlUtil.generateQueryString(queryParamsMap, true); - //System.out.println("规范化后的请求参数串:" + queryString); - if (null == queryString) { - //System.out.println("构造规范化的请求字符串失败!"); - return null; - } - String signString = SignUtil.generateHmacSHA1SignString("GET", "/", queryString); - //System.out.println("构造的签名字符串:" + signString); - if (null == signString) { - //System.out.println("构造签名字符串失败"); - return null; - } - String signature = SignUtil.hmacSHA1Sign(accessKeySecret + "&", signString); - //System.out.println("计算的得到的签名:" + signature); - if (null == signature) { - //System.out.println("计算签名失败!"); - return null; - } - /** - * 4.将签名加入到第1步获取的请求字符串 - */ - String queryStringWithSign = "Signature=" + signature + "&" + queryString; - //System.out.println("带有签名的请求字符串:" + queryStringWithSign); - return queryStringWithSign; - } - - public static NlsToken synQueryToken(String queryString) { - String url = BASE_URL + "/" + "?" + queryString; - HashMap headers = new HashMap<>(1); - headers.put("Accept", "application/json"); - NlsTokenResponse tokenResponse = HttpUtil.doGet(url, null, headers, new TypeReference() {}); - if (tokenResponse != null && tokenResponse.getToken() != null) { - saveToken(tokenResponse.getToken()); - return tokenResponse.getToken(); - } else { - return null; - } - } - - public static void aynQueryToken(String queryString, TokenListener tokenListener) { - String url = BASE_URL + "/" + "?" + queryString; - HashMap headers = new HashMap<>(1); - headers.put("Accept", "application/json"); - HttpUtil.doGet(url, null, headers, new HttpCallBack() { - @Override - public void onSuccess(NlsTokenResponse data) { - if (data != null && data.getToken() != null) { - saveToken(data.getToken()); - if (tokenListener != null) { - tokenListener.onSuccess(data.getToken().getId()); - } - } - } - - @Override - public void onException(Exception e) { - if (tokenListener != null) { - tokenListener.onError(e); - } - } - }); - } - -} diff --git a/src/main/java/com/zl/aliyun/util/Base64Encoder.java b/src/main/java/com/zl/aliyun/util/Base64Encoder.java deleted file mode 100644 index 342a364..0000000 --- a/src/main/java/com/zl/aliyun/util/Base64Encoder.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.zl.aliyun.util; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/02 17:38 - */ -public class Base64Encoder { - private static final char last2byte = (char) Integer - .parseInt("00000011", 2); - private static final char last4byte = (char) Integer - .parseInt("00001111", 2); - private static final char last6byte = (char) Integer - .parseInt("00111111", 2); - private static final char lead6byte = (char) Integer - .parseInt("11111100", 2); - private static final char lead4byte = (char) Integer - .parseInt("11110000", 2); - private static final char lead2byte = (char) Integer - .parseInt("11000000", 2); - private static final char[] encodeTable = new char[]{'A', 'B', 'C', 'D', - 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', - 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', - 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/'}; - - /** - * Base64 encoding. - * - * @param from The src data. - * @return - */ - public static String encode(byte[] from) { - StringBuffer to = new StringBuffer((int) (from.length * 1.34) + 3); - int num = 0; - char currentByte = 0; - for (int i = 0; i < from.length; i++) { - num = num % 8; - while (num < 8) { - switch (num) { - case 0: - currentByte = (char) (from[i] & lead6byte); - currentByte = (char) (currentByte >>> 2); - break; - case 2: - currentByte = (char) (from[i] & last6byte); - break; - case 4: - currentByte = (char) (from[i] & last4byte); - currentByte = (char) (currentByte << 2); - if ((i + 1) < from.length) { - currentByte |= (from[i + 1] & lead2byte) >>> 6; - } - break; - case 6: - currentByte = (char) (from[i] & last2byte); - currentByte = (char) (currentByte << 4); - if ((i + 1) < from.length) { - currentByte |= (from[i + 1] & lead4byte) >>> 4; - } - break; - } - to.append(encodeTable[currentByte]); - num += 6; - } - } - if (to.length() % 4 != 0) { - for (int i = 4 - to.length() % 4; i > 0; i--) { - to.append("="); - } - } - return to.toString(); - } -} diff --git a/src/main/java/com/zl/aliyun/util/DateUtil.java b/src/main/java/com/zl/aliyun/util/DateUtil.java deleted file mode 100644 index 6db23bf..0000000 --- a/src/main/java/com/zl/aliyun/util/DateUtil.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.zl.aliyun.util; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.SimpleTimeZone; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/02 17:49 - */ -public class DateUtil { - private final static String TIME_ZONE = "GMT"; - private final static String FORMAT_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss'Z'"; - - /** - * 获取时间戳 - * 符合ISO8601规范,并需要使用UTC时间,时区为+0 - */ - public static String getISO8601Time(Date date) { - Date nowDate = date; - if (null == date) { - nowDate = new Date(); - } - SimpleDateFormat df = new SimpleDateFormat(FORMAT_ISO8601); - df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE)); - return df.format(nowDate); - } -} diff --git a/src/main/java/com/zl/aliyun/util/JsonUtil.java b/src/main/java/com/zl/aliyun/util/JsonUtil.java deleted file mode 100644 index a213c3e..0000000 --- a/src/main/java/com/zl/aliyun/util/JsonUtil.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.zl.aliyun.util; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.TypeReference; - -import java.lang.reflect.Type; -import java.util.List; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description JSON解析工具 - * @date 2019/09/02 11:21 - */ - -public class JsonUtil { - /** - * @param object 类的实例 - * @return JSON字符串 - */ - public static String toJson(Object object) { - if (null == object) { - return null; - } - return JSON.toJSONString(object); - } - - /** - * @param 泛型声明 - * @param json JSON字符串 - * @param clazz 要转换对象的类型 - * @return - */ - public static T fromJson(String json, Class clazz) { - if (null == json || json.length() <= 0) { return null; } - return JSON.parseObject(json, clazz); - } - - public static T fromJson(String json, TypeReference type) { - if (null == json || json.length() <= 0) { return null; } - return JSON.parseObject(json, type); - } - - public static T fromJson(String json, Type type) { - if (null == json || json.length() <= 0) { return null; } - return JSON.parseObject(json, type); - } - - /** - * 解析json使用泛型转换为对应List - * - * @return - */ - public static List json2List(String json, Class clazz) { - if (null == json || json.length() <= 0) { return null; } - return JSON.parseArray(json, clazz); - } - -} diff --git a/src/main/java/com/zl/aliyun/util/SignUtil.java b/src/main/java/com/zl/aliyun/util/SignUtil.java deleted file mode 100644 index c08bcf9..0000000 --- a/src/main/java/com/zl/aliyun/util/SignUtil.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.zl.aliyun.util; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import java.io.IOException; -import java.util.Map; -import java.util.UUID; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/03 10:24 - */ -public class SignUtil { - private final static String CHARSET_UTF8 = "utf8"; - private final static String SEPARATOR = "&"; - private static final String ENCODING = "UTF-8"; - - /** - * 获取UUID - */ - public static String getUniqueNonce() { - UUID uuid = UUID.randomUUID(); - return uuid.toString(); - } - - public static String generateHmacSHA1SignString(String method, String urlPath, Map params) { - String queryString = UrlUtil.generateQueryString(params, true); - return generateHmacSHA1SignString(method, urlPath, queryString); - } - - public static String generateHmacSHA1SignString(String method, String urlPath, String queryString) { - StringBuilder strBuilderSign = new StringBuilder(); - strBuilderSign.append(method); - strBuilderSign.append(SEPARATOR); - strBuilderSign.append(UrlUtil.percentEncode(urlPath)); - strBuilderSign.append(SEPARATOR); - strBuilderSign.append(UrlUtil.percentEncode(queryString)); - return strBuilderSign.toString(); - } - - public static byte[] hmacSHA1Signature(String secret, String baseString) throws Exception { - if (StringUtil.isEmpty(secret)) { - throw new IOException("secret can not be empty"); - } - if (StringUtil.isEmpty(baseString)) { - return null; - } - Mac mac = Mac.getInstance("HmacSHA1"); - SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(CHARSET_UTF8), ENCODING); - mac.init(keySpec); - return mac.doFinal(baseString.getBytes(CHARSET_UTF8)); - } - - public static String hmacSHA1Sign(String secret, String baseString) { - try { - byte[] signData = hmacSHA1Signature(secret, baseString); - if (signData != null && signData.length > 0) { - return Base64Encoder.encode(signData); - } else { - return null; - } - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - -} diff --git a/src/main/java/com/zl/aliyun/util/StringUtil.java b/src/main/java/com/zl/aliyun/util/StringUtil.java deleted file mode 100644 index 9c5609c..0000000 --- a/src/main/java/com/zl/aliyun/util/StringUtil.java +++ /dev/null @@ -1,234 +0,0 @@ -package com.zl.aliyun.util; - -import java.io.UnsupportedEncodingException; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/02 17:41 - */ -public class StringUtil { - - public static boolean isEmpty(String value) { - if (value != null && value.length() > 0) { - return false; - } - return true; - } - - public static List stringToSList(String data) { - return stringToSList(data, ","); - } - - public static List stringToSList(String data, String regex) { - if (isEmpty(data) || isEmpty(regex)) { - return null; - } - return new ArrayList<>(Arrays.asList(data.split(regex))); - } - - public static List stringToLList(String data) { - return stringToLList(data, ","); - } - - public static List stringToLList(String data, String regex) { - if (isEmpty(data) || isEmpty(regex)) { - return null; - } - String[] strings = data.split(regex); - List list = new ArrayList<>(); - for (String string : strings) { - Long values = stringToLong(string); - if (values != null) { - list.add(values); - } - } - return list; - } - - public static Integer stringToInteger(String data) { - Integer value = null; - try { - if (!isEmpty(data)) { - value = Integer.parseInt(data); - } - } catch (NumberFormatException e) { - e.printStackTrace(); - } - return value; - } - - public static Long stringToLong(String data) { - Long value = null; - try { - if (!isEmpty(data)) { - value = Long.parseLong(data); - } - } catch (NumberFormatException e) { - e.printStackTrace(); - } - return value; - } - - public static Double stringToDouble(String data) { - Double value = null; - try { - if (!isEmpty(data)) { - value = Double.parseDouble(data); - } - } catch (NumberFormatException e) { - e.printStackTrace(); - } - return value; - } - - public static String IntegerToString(Integer data) { - if (data != null) { - return String.valueOf(data); - } else { - return ""; - } - } - - public static String doubleToString(Double data) { - if (data == null) { return ""; } - - return doubleToString(data, "%.2f"); - } - - public static String doubleToString(Double data, String format) { - String value = null; - if (data != null) { - try { - value = String.format(format, data); - } catch (IllegalFormatException ex) { - ex.printStackTrace(); - } - } - if (isEmpty(value)) { - value = "0"; - } - return value; - } - - public static Boolean isNumeric(String str) { - if (null == str || str.length() == 0) { - return false; - } - for (int i = str.length(); --i >= 0; ) { - if (!Character.isDigit(str.charAt(i))) { - return false; - } - } - return true; - } - - public static String getRandNumberString() { - int min = 10000; - int max = 99999; - Random random = new Random(); - int randNumber = random.nextInt(max) % (max - min + 1) + min; - StringBuilder sb = new StringBuilder(); - sb.append(System.currentTimeMillis()); - sb.append(randNumber); - return sb.toString(); - } - - public static String join(List list, String split) { - if (null == list || list.size() == 0 || null == split) { - return null; - } - String strResult = ""; - StringBuilder stringBuilder = new StringBuilder(); - int splitLength = split.length(); - for (T tmp : list) { - stringBuilder.append(tmp); - stringBuilder.append(split); - } - strResult = stringBuilder.toString(); - strResult = strResult.substring(0, strResult.length() - splitLength); - return strResult; - } - - /** - * 字符串中批量替换某些字符 - * - * @param replacementDefine 要替换的定义,key为被替换掉的值,支持正则表达式;value为替换之后的值(value为$等正则字符时会报错) - * @param string 要检索替换的字符串主体 - * @return 替换之后的字符串 - * @throws IllegalStateException If no match has yet been attempted, or if the previous match operation failed - * @throws IllegalArgumentException If the replacement string refers to a named-capturing group that does not exist in the pattern - * @throws IndexOutOfBoundsException If the replacement string refers to a capturing group that does not exist in the pattern - */ - public static String batchReplace(Map replacementDefine, String string) { - if (null == replacementDefine || replacementDefine.size() == 0 || null == string || string.length() == 0) { - return ""; - } - Set defineKetSet = replacementDefine.keySet(); - String regex = "(" + StringUtil.join(new ArrayList<>(defineKetSet), ")|(") + ")"; - Map replaceMap = new HashMap<>(); - int keyCount = 1; - for (String key : defineKetSet) { - replaceMap.put(keyCount++, replacementDefine.get(key)); - } - return batchReplaceInString(regex, replaceMap, string); - } - - /** - * 内部使用替换核心,专服务于batchReplace,filterBadWord - * - * @param regex 替换的正则表达式 - * @param replaceMap 被替换的单元定义 - * @param string - * @return - */ - private static String batchReplaceInString(String regex, Map replaceMap, String string) { - Set replaceKeys = replaceMap.keySet(); - Matcher matcher = Pattern.compile(regex).matcher(string); - StringBuffer sb = new StringBuffer(); - while (matcher.find()) { - for (Integer intKey : replaceKeys) { - if (null != matcher.group(intKey)) { - matcher.appendReplacement(sb, replaceMap.get(intKey)); - } - } - } - matcher.appendTail(sb); - return sb.toString(); - } - - public static String getUrlStringValue(String name, String value) { - try { - return new String(value.getBytes("ISO-8859-1"), "UTF-8"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - return null; - } - } - - public static String getUrlStringValue(String value) { - return getUrlStringValue("文本", value); - } - - public static List ids(String ids) { - String[] sids = ids.split(","); - List list = new ArrayList(); - for (String sid : sids) { - try { - list.add(Long.valueOf(sid)); - } catch (NumberFormatException ignored) { - - } - } - HashSet hs = new HashSet(list); - list.clear(); - for (Long h : hs) { - list.add(h); - } - return list; - } -} diff --git a/src/main/java/com/zl/aliyun/util/UrlUtil.java b/src/main/java/com/zl/aliyun/util/UrlUtil.java deleted file mode 100644 index 5e5a88b..0000000 --- a/src/main/java/com/zl/aliyun/util/UrlUtil.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.zl.aliyun.util; - -import java.net.URLEncoder; -import java.util.Arrays; -import java.util.Map; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/02 18:00 - */ -public class UrlUtil { - private final static String URL_ENCODING = "UTF-8"; - - /** - * URL编码 使用UTF-8字符集按照 RFC3986 规则编码请求参数和参数取值 - */ - public static String percentEncode(String value) { - try { - return value != null ? URLEncoder.encode(value, URL_ENCODING).replace("+", "%20") - .replace("*", "%2A").replace("%7E", "~") : null; - } catch (Exception ex) { - ex.printStackTrace(); - return null; - } - } - - public static String generateQueryString(Map params, boolean isEncode) { - if (null == params || params.size() < 1) {return null;} - String[] sortedKeys = params.keySet().toArray(new String[] {}); - Arrays.sort(sortedKeys); - StringBuilder queryBuilder = new StringBuilder(); - for (String key : sortedKeys) { - if (isEncode) { - queryBuilder.append(percentEncode(key)).append("=") - .append(percentEncode(params.get(key))).append("&"); - } else { - queryBuilder.append(key).append("=") - .append(params.get(key)).append("&"); - } - } - if (queryBuilder.length() > 1) { - queryBuilder.setLength(queryBuilder.length() - 1); - } - return queryBuilder.toString(); - } - - public static String urlEncode(String url) { - if (!StringUtil.isEmpty(url)) { - try { - url = URLEncoder.encode(url, URL_ENCODING); - } catch (Exception e) { - e.printStackTrace(); - } - } - return url; - } -} diff --git a/src/main/java/com/zl/aliyun/util/http/ByteContentFile.java b/src/main/java/com/zl/aliyun/util/http/ByteContentFile.java deleted file mode 100644 index 76046aa..0000000 --- a/src/main/java/com/zl/aliyun/util/http/ByteContentFile.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.zl.aliyun.util.http; - -import java.io.Serializable; - -/** - * @author ZL - */ -public final class ByteContentFile implements Serializable { - private static final long serialVersionUID = 127254956313902461L; - private String reqName; - private String fileName; - private byte[] content; - - public ByteContentFile() { - } - - public ByteContentFile(String reqName, String fileName, byte[] content) { - this.reqName = reqName; - this.fileName = fileName; - this.content = content; - } - - public String getReqName() { - return reqName; - } - - public void setReqName(String reqName) { - this.reqName = reqName; - } - - public String getFileName() { - return fileName; - } - - public void setFileName(String fileName) { - this.fileName = fileName; - } - - public byte[] getContent() { - return content; - } - - public void setContent(byte[] content) { - this.content = content; - } - - @Override - public String toString() { - return "ByteContentFile{" + - "reqName='" + reqName + '\'' + - ", fileName='" + fileName + '\'' + - ", content=" + content.length + - '}'; - } -} diff --git a/src/main/java/com/zl/aliyun/util/http/FileContentFile.java b/src/main/java/com/zl/aliyun/util/http/FileContentFile.java deleted file mode 100644 index 9f840b4..0000000 --- a/src/main/java/com/zl/aliyun/util/http/FileContentFile.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.zl.aliyun.util.http; - -import java.io.File; -import java.io.Serializable; - -/** - * @author zl - * @Version 1.0 - * @Description TODO - * @date 2018/11/02 10:21 - */ -public class FileContentFile implements Serializable { - private static final long serialVersionUID = -6339050941229672951L; - private String reqName; - private String fileName; - private File file; - - public FileContentFile() { - } - - public FileContentFile(String reqName, String fileName, File file) { - this.reqName = reqName; - this.fileName = fileName; - this.file = file; - } - - public String getReqName() { - return reqName; - } - - public void setReqName(String reqName) { - this.reqName = reqName; - } - - public String getFileName() { - return fileName; - } - - public void setFileName(String fileName) { - this.fileName = fileName; - } - - public File getFile() { - return file; - } - - public void setFile(File file) { - this.file = file; - } - - @Override - public String toString() { - return "FileContentFile{" + - "reqName='" + reqName + '\'' + - ", fileName='" + fileName + '\'' + - ", file=" + file.getAbsolutePath() + - '}'; - } -} diff --git a/src/main/java/com/zl/aliyun/util/http/HttpCallBack.java b/src/main/java/com/zl/aliyun/util/http/HttpCallBack.java deleted file mode 100644 index 17c7b8c..0000000 --- a/src/main/java/com/zl/aliyun/util/http/HttpCallBack.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.zl.aliyun.util.http; - -/** - * @author zl - * @Version 1.0 - * @Description TODO - * @date 2019/01/16 14:51 - */ -public interface HttpCallBack { - /** - * 网络请求成功 - * - * @param data - * @return - */ - void onSuccess(T data); - - /** - * 网络请求异常 - * - * @param e - * @return - */ - void onException(Exception e); -} diff --git a/src/main/java/com/zl/aliyun/util/http/HttpUtil.java b/src/main/java/com/zl/aliyun/util/http/HttpUtil.java deleted file mode 100644 index 65d0b79..0000000 --- a/src/main/java/com/zl/aliyun/util/http/HttpUtil.java +++ /dev/null @@ -1,261 +0,0 @@ -package com.zl.aliyun.util.http; - -import com.alibaba.fastjson.TypeReference; -import com.zl.aliyun.util.JsonUtil; -import com.zl.aliyun.util.StringUtil; -import okhttp3.*; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -/** - * @author zl - * @Version 1.0 - * @Description TODO - * @date 2019/01/16 14:52 - */ -public class HttpUtil { - private static long TIMEOUT_WRITE = 20; - private static long TIMEOUT_READ = 20; - private static long TIMEOUT_CONNECT = 20; - - private volatile static OkHttpClient mClient; - - public static OkHttpClient getClient() { - if (null == mClient) { - synchronized (OkHttpClient.class) { - if (null == mClient) { - OkHttpClient.Builder builder = new OkHttpClient.Builder(); - builder.writeTimeout(TIMEOUT_WRITE, TimeUnit.SECONDS); - builder.readTimeout(TIMEOUT_READ, TimeUnit.SECONDS); - builder.connectTimeout(TIMEOUT_CONNECT, TimeUnit.SECONDS); - mClient = builder.build(); - } - } - } - return mClient; - } - - public static void setTimeoutWrite(long timeoutWrite) { - TIMEOUT_WRITE = timeoutWrite; - } - - public static void setTimeoutRead(long timeoutRead) { - TIMEOUT_READ = timeoutRead; - } - - public static void setTimeoutConnect(long timeoutConnect) { - TIMEOUT_CONNECT = timeoutConnect; - } - - public static void doGet(String url, Map params, Map headers, HttpCallBack callBack) { - String reqUrl = url; - if (params != null && params.size() > 0) { reqUrl = reqUrl + "?" + parseUrlRequest(params); } - Request.Builder builder = new Request.Builder(); - builder.url(reqUrl); - if (headers != null && headers.size() > 0) { builder.headers(getHeaders(headers)); } - request(builder.build(), callBack); - } - - public static T doGet(String url, Map params, Map headers, TypeReference type) { - String reqUrl = url; - if (params != null && params.size() > 0) { reqUrl = reqUrl + "?" + parseUrlRequest(params); } - Request.Builder builder = new Request.Builder(); - builder.url(reqUrl); - if (headers != null && headers.size() > 0) { builder.headers(getHeaders(headers)); } - return request(builder.build(), type); - } - - public static void doPost(String url, Map params, HttpCallBack callBack) { - requestPost(url, getBody(params), null, callBack); - } - - public static void doPostFile(String url, Map params, FileContentFile file, HttpCallBack callBack) { - requestPost(url, getBody(params, file), null, callBack); - } - - public static void doPostFile(String url, Map params, FileContentFile file, Map heardes, HttpCallBack callBack) { - requestPost(url, getBody(params, file), heardes, callBack); - } - - public static T doPost(String url, Map params, TypeReference type) { - return requestPost(url, getBody(params), null, type); - } - - public static T doPostJson(String url, Map params, TypeReference type) { - Map heardes = new HashMap<>(1); - heardes.put("content-type", "application/json;charset:utf-8"); - return requestPost(url, getBodyForJson(params), heardes, type); - } - - public static T doPostFile(String url, Map params, ByteContentFile file, TypeReference type) { - return requestPost(url, getBody(params, file), null, type); - } - - public static void doPostFile(String url, Map params, ByteContentFile file, HttpCallBack callBack) { - requestPost(url, getBody(params, file), null, callBack); - } - - public static T doPostFile(String url, Map params, FileContentFile file, TypeReference type) { - return requestPost(url, getBody(params, file), null, type); - } - - public static T doPostFile(String url, Map params, FileContentFile file, Map heardes, TypeReference type) { - return requestPost(url, getBody(params, file), heardes, type); - } - - public static void requestPost(String url, RequestBody body, Map headers, HttpCallBack callBack) { - Request.Builder builder = new Request.Builder(); - builder.url(url); - if (headers != null && headers.size() > 0) { builder.headers(getHeaders(headers)); } - builder.post(body); - request(builder.build(), callBack); - } - - public static T requestPost(String url, RequestBody body, Map headers, TypeReference type) { - Request.Builder builder = new Request.Builder(); - builder.url(url); - if (headers != null && headers.size() > 0) { builder.headers(getHeaders(headers)); } - builder.post(body); - return request(builder.build(), type); - } - - public static void request(Request request, final HttpCallBack callBack) { - getClient().newCall(request).enqueue(new Callback() { - @Override - public void onFailure(Call call, IOException e) { - if (callBack != null) { callBack.onException(e); } - } - - @Override - public void onResponse(Call call, Response response) throws IOException { - String result = response.body().string(); - if (!StringUtil.isEmpty(result)) { - if (callBack != null) { - try { - Type type = ((ParameterizedType)callBack.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; - callBack.onSuccess(JsonUtil.fromJson(result, type)); - } catch (Exception e) { - callBack.onException(e); - } - } - } - } - }); - } - - public static T request(Request request, TypeReference type) { - try { - Response response = getClient().newCall(request).execute(); - String result = response.body().string(); - System.out.println(result); - if (!StringUtil.isEmpty(result)) { - return JsonUtil.fromJson(result, type); - } - } catch ( - IOException e) { - e.printStackTrace(); - } - return null; - } - - public static Headers getHeaders(Map headers) { - Headers.Builder builder = new Headers.Builder(); - if (headers != null && headers.size() > 0) { - for (Map.Entry entry : headers.entrySet()) { - builder.add(entry.getKey(), urlEncoderUTF8(entry.getValue().toString())); - } - } - return builder.build(); - } - - public static RequestBody getBody(Map params) { - FormBody.Builder bodyBuilder = new FormBody.Builder(); - if (params != null && params.size() > 0) { - for (Map.Entry entry : params.entrySet()) { - bodyBuilder.add(entry.getKey(), urlEncoderUTF8(entry.getValue().toString())); - } - } - return bodyBuilder.build(); - } - - public static RequestBody getBodyForJson(Map params) { - String json = JsonUtil.toJson(params); - MediaType mediaType = MediaType.parse("application/json,charset=utf-8"); - RequestBody requestBody = RequestBody.create(mediaType, json); - return requestBody; - } - - public static RequestBody getBody(Map params, ByteContentFile file) { - MultipartBody.Builder bodyBuilder = new MultipartBody.Builder(); - bodyBuilder.setType(MultipartBody.FORM); - if (params != null && params.size() > 0) { - for (Map.Entry entry : params.entrySet()) { - bodyBuilder.addFormDataPart(entry.getKey(), urlEncoderUTF8(entry.getValue().toString())); - } - } - if (file != null && file.getContent() != null) { - bodyBuilder.addFormDataPart(file.getReqName(), file.getFileName(), RequestBody.create(MediaType.parse("application/octet-stream"), file.getContent())); - } - return bodyBuilder.build(); - } - - public static RequestBody getBody(Map params, FileContentFile file) { - MultipartBody.Builder bodyBuilder = new MultipartBody.Builder(); - bodyBuilder.setType(MultipartBody.FORM); - if (params != null && params.size() > 0) { - for (Map.Entry entry : params.entrySet()) { - bodyBuilder.addFormDataPart(entry.getKey(), urlEncoderUTF8(entry.getValue().toString())); - } - } - if (file != null && file.getFile() != null) { - bodyBuilder.addFormDataPart(file.getReqName(), file.getFileName(), RequestBody.create(MediaType.parse("application/octet-stream"), file.getFile())); - } - return bodyBuilder.build(); - } - - public static RequestBody getBody(Map params, List fileList) { - MultipartBody.Builder bodyBuilder = new MultipartBody.Builder(); - bodyBuilder.setType(MultipartBody.FORM); - if (params != null && params.size() > 0) { - for (Map.Entry entry : params.entrySet()) { - bodyBuilder.addFormDataPart(entry.getKey(), urlEncoderUTF8(entry.getValue().toString())); - } - } - if (fileList != null && fileList.size() > 0) { - for (FileContentFile fileContentFile : fileList) { - if (fileContentFile != null && fileContentFile.getFile() != null) { - bodyBuilder.addFormDataPart(fileContentFile.getReqName(), fileContentFile.getFileName(), RequestBody.create(MediaType.parse("application/octet-stream"), fileContentFile.getFile())); - } - } - } - return bodyBuilder.build(); - } - - public static String parseUrlRequest(Map params) { - StringBuffer buffer = new StringBuffer(); - if (params != null && params.size() > 0) { - for (Map.Entry entry : params.entrySet()) { - if (buffer.length() > 0) { buffer.append("&"); } - buffer.append(String.format("%s=%s", urlEncoderUTF8(entry.getKey()), urlEncoderUTF8(entry.getValue().toString()))); - } - } - return buffer.toString(); - } - - public static String urlEncoderUTF8(String s) { - try { - return URLEncoder.encode(s, "UTF-8"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - return s; - } -} diff --git a/src/test/java/com/zl/demo/nls/NLSDemo.java b/src/test/java/com/zl/demo/nls/NLSDemo.java deleted file mode 100644 index 8de49db..0000000 --- a/src/test/java/com/zl/demo/nls/NLSDemo.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.zl.demo.nls; - -import com.zl.aliyun.nls.TokenListener; -import com.zl.aliyun.nls.TokenUtil; -import org.junit.Test; - -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * @author ZL @朱林 - * @Version 1.0 - * @Description TODO - * @date 2019/09/03 16:26 - */ -public class NLSDemo { - private static final String accessKeyId = "LTAIQDnXhioZ6TJF"; - private static final String accessKeySecret = "njZGVbnrPph1dvW5ykMYgdFDO3WOBA"; - - @Test - public void testAsync() { - TokenUtil.getToken(accessKeyId, accessKeySecret, new TokenListener() { - @Override - public void onSuccess(String token) { - System.out.println("token:"+token); - } - - @Override - public void onError(Exception e) { - System.out.println("Exception:"+e); - } - }); - String token= TokenUtil.getToken(accessKeyId, accessKeySecret); - System.out.println("token:"+token); - } - @Test - public void testSync() { - String token= TokenUtil.getToken(accessKeyId, accessKeySecret); - System.out.println("token:"+token); - } - - @Test - public void testExpireTime(){ - long time=1567670678L; - Date date=new Date(time*1000); - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - System.out.println(df.format(date)); - } -}