|
@@ -3,7 +3,6 @@ package cn.com.qmth.examcloud.exchange.inner.service.upyun;
|
|
|
import java.io.BufferedReader;
|
|
|
import java.io.File;
|
|
|
import java.io.FileInputStream;
|
|
|
-import java.io.FileOutputStream;
|
|
|
import java.io.IOException;
|
|
|
import java.io.InputStream;
|
|
|
import java.io.InputStreamReader;
|
|
@@ -15,15 +14,19 @@ import java.security.MessageDigest;
|
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.Date;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.LinkedList;
|
|
|
-import java.util.List;
|
|
|
import java.util.Locale;
|
|
|
import java.util.Map;
|
|
|
import java.util.TimeZone;
|
|
|
|
|
|
import main.java.com.upyun.UpYunUtils;
|
|
|
|
|
|
+/**
|
|
|
+ * upyun SDK定制版
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @date 2018年11月21日
|
|
|
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
|
|
|
+ */
|
|
|
public class UpYunClient {
|
|
|
|
|
|
/**
|
|
@@ -45,8 +48,6 @@ public class UpYunClient {
|
|
|
|
|
|
private final String DATE = "Date";
|
|
|
|
|
|
- private final String CONTENT_LENGTH = "Content-Length";
|
|
|
-
|
|
|
private final String CONTENT_MD5 = "Content-MD5";
|
|
|
|
|
|
private final String CONTENT_SECRET = "Content-Secret";
|
|
@@ -65,14 +66,8 @@ public class UpYunClient {
|
|
|
|
|
|
private final String X_UPYUN_FILE_DATE = "x-upyun-file-date";
|
|
|
|
|
|
- private final String METHOD_HEAD = "HEAD";
|
|
|
-
|
|
|
- private final String METHOD_GET = "GET";
|
|
|
-
|
|
|
private final String METHOD_PUT = "PUT";
|
|
|
|
|
|
- private final String METHOD_DELETE = "DELETE";
|
|
|
-
|
|
|
/**
|
|
|
* 根据网络条件自动选择接入点:v0.api.upyun.com
|
|
|
*/
|
|
@@ -266,156 +261,6 @@ public class UpYunClient {
|
|
|
return VERSION;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 获取总体空间的占用量
|
|
|
- *
|
|
|
- * @param path
|
|
|
- * 目标路径
|
|
|
- * @return 空间占用量,失败时返回 -1
|
|
|
- */
|
|
|
- public long getBucketUsage() {
|
|
|
- long usage = -1;
|
|
|
-
|
|
|
- String result = HttpAction(METHOD_GET, formatPath("/") + "/?usage");
|
|
|
-
|
|
|
- if (!isEmpty(result)) {
|
|
|
-
|
|
|
- try {
|
|
|
- usage = Long.parseLong(result.trim());
|
|
|
- } catch (NumberFormatException e) {
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return usage;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取某个子目录的占用量
|
|
|
- *
|
|
|
- * @param path
|
|
|
- * 目标路径
|
|
|
- * @return 空间占用量,失败时返回 -1
|
|
|
- */
|
|
|
- @Deprecated
|
|
|
- public long getFolderUsage(String path) {
|
|
|
-
|
|
|
- long usage = -1;
|
|
|
-
|
|
|
- String result = HttpAction(METHOD_GET, formatPath(path) + "/?usage");
|
|
|
-
|
|
|
- if (!isEmpty(result)) {
|
|
|
-
|
|
|
- try {
|
|
|
- usage = Long.parseLong(result.trim());
|
|
|
- } catch (NumberFormatException e) {
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return usage;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 上传文件
|
|
|
- *
|
|
|
- * @param filePath
|
|
|
- * 文件路径(包含文件名)
|
|
|
- * @param datas
|
|
|
- * 文件内容
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean writeFile(String filePath, byte[] datas) {
|
|
|
- return writeFile(filePath, datas, false, null);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 上传文件
|
|
|
- *
|
|
|
- * @param filePath
|
|
|
- * 文件路径(包含文件名)
|
|
|
- * @param datas
|
|
|
- * 文件内容
|
|
|
- * @param auto
|
|
|
- * 是否自动创建父级目录(最多10级)
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean writeFile(String filePath, byte[] datas, boolean auto) {
|
|
|
- return writeFile(filePath, datas, auto, null);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 上传文件
|
|
|
- *
|
|
|
- * @param filePath
|
|
|
- * 文件路径(包含文件名)
|
|
|
- * @param datas
|
|
|
- * 文件内容
|
|
|
- * @param auto
|
|
|
- * 是否自动创建父级目录(最多10级)
|
|
|
- * @param params
|
|
|
- * 额外参数
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean writeFile(String filePath, byte[] datas, boolean auto,
|
|
|
- Map<String, String> params) {
|
|
|
-
|
|
|
- return HttpAction(METHOD_PUT, formatPath(filePath), datas, null, auto, params) != null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 上传文件
|
|
|
- *
|
|
|
- * @param filePath
|
|
|
- * 文件路径(包含文件名)
|
|
|
- * @param String
|
|
|
- * datas 文件内容
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean writeFile(String filePath, String datas) {
|
|
|
- return writeFile(filePath, datas, false, null);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 上传文件
|
|
|
- *
|
|
|
- * @param filePath
|
|
|
- * 文件路径(包含文件名)
|
|
|
- * @param String
|
|
|
- * datas 文件内容
|
|
|
- * @param auto
|
|
|
- * 是否自动创建父级目录(最多10级)
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean writeFile(String filePath, String datas, boolean auto) {
|
|
|
- return writeFile(filePath, datas, auto, null);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 上传文件
|
|
|
- *
|
|
|
- * @param filePath
|
|
|
- * 文件路径(包含文件名)
|
|
|
- * @param String
|
|
|
- * datas 文件内容
|
|
|
- * @param auto
|
|
|
- * 是否自动创建父级目录(最多10级)
|
|
|
- * @param params
|
|
|
- * 额外参数
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean writeFile(String filePath, String datas, boolean auto,
|
|
|
- Map<String, String> params) {
|
|
|
-
|
|
|
- boolean result = false;
|
|
|
-
|
|
|
- try {
|
|
|
- result = writeFile(filePath, datas.getBytes(UTF8), auto, params);
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 上传文件
|
|
|
*
|
|
@@ -562,162 +407,6 @@ public class UpYunClient {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 读取文件
|
|
|
- *
|
|
|
- * @param filePath
|
|
|
- * 文件路径(包含文件名)
|
|
|
- * @return 文件内容 或 null
|
|
|
- */
|
|
|
- public String readFile(String filePath) {
|
|
|
- return HttpAction(METHOD_GET, formatPath(filePath));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 读取文件
|
|
|
- *
|
|
|
- * @param filePath
|
|
|
- * 文件路径(包含文件名)
|
|
|
- * @param file
|
|
|
- * 临时文件
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean readFile(String filePath, File file) {
|
|
|
-
|
|
|
- String result = HttpAction(METHOD_GET, formatPath(filePath), null, file, false);
|
|
|
-
|
|
|
- return "".equals(result);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取文件信息
|
|
|
- *
|
|
|
- * @param filePath
|
|
|
- * 文件路径(包含文件名)
|
|
|
- * @return 文件信息 或 null
|
|
|
- */
|
|
|
- public Map<String, String> getFileInfo(String filePath) {
|
|
|
-
|
|
|
- HttpAction(METHOD_HEAD, formatPath(filePath));
|
|
|
-
|
|
|
- // 判断是否存在文件信息
|
|
|
- if (isEmpty(fileType) && isEmpty(fileSize) && isEmpty(fileDate)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- Map<String, String> mp = new HashMap<String, String>();
|
|
|
- mp.put("type", fileType);
|
|
|
- mp.put("size", fileSize);
|
|
|
- mp.put("date", fileDate);
|
|
|
-
|
|
|
- return mp;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 删除文件
|
|
|
- *
|
|
|
- * @param filePath
|
|
|
- * 文件路径(包含文件名)
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean deleteFile(String filePath) {
|
|
|
-
|
|
|
- return HttpAction(METHOD_DELETE, formatPath(filePath)) != null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 创建目录
|
|
|
- *
|
|
|
- * @param path
|
|
|
- * 目录路径
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean mkDir(String path) {
|
|
|
- return mkDir(path, false);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 创建目录
|
|
|
- *
|
|
|
- * @param path
|
|
|
- * 目录路径
|
|
|
- * @param auto
|
|
|
- * 是否自动创建父级目录(最多10级)
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean mkDir(String path, boolean auto) {
|
|
|
-
|
|
|
- Map<String, String> params = new HashMap<String, String>(1);
|
|
|
- params.put(PARAMS.KEY_MAKE_DIR.getValue(), "true");
|
|
|
-
|
|
|
- String result = HttpAction(METHOD_PUT, formatPath(path), null, null, auto, params);
|
|
|
-
|
|
|
- return result != null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 读取目录列表
|
|
|
- *
|
|
|
- * @param path
|
|
|
- * 目录路径
|
|
|
- * @return List<FolderItem> 或 null
|
|
|
- */
|
|
|
- public List<FolderItem> readDir(String path) {
|
|
|
-
|
|
|
- String result = HttpAction(METHOD_GET, formatPath(path) + SEPARATOR);
|
|
|
-
|
|
|
- if (isEmpty(result))
|
|
|
- return null;
|
|
|
-
|
|
|
- List<FolderItem> list = new LinkedList<FolderItem>();
|
|
|
-
|
|
|
- String[] datas = result.split("\n");
|
|
|
-
|
|
|
- for (int i = 0; i < datas.length; i++) {
|
|
|
- if (datas[i].indexOf("\t") > 0) {
|
|
|
- list.add(new FolderItem(datas[i]));
|
|
|
- }
|
|
|
- }
|
|
|
- return list;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 删除目录
|
|
|
- *
|
|
|
- * @param path
|
|
|
- * 目录路径
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean rmDir(String path) {
|
|
|
- return HttpAction(METHOD_DELETE, formatPath(path)) != null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取上传文件后的信息(仅图片空间有返回数据)
|
|
|
- *
|
|
|
- * @param key
|
|
|
- * 信息字段名(x-upyun-width、x-upyun-height、x-upyun-frames、x-upyun-file
|
|
|
- * -type)
|
|
|
- * @return value or NULL
|
|
|
- * @deprecated
|
|
|
- */
|
|
|
- public String getWritedFileInfo(String key) {
|
|
|
-
|
|
|
- if (isEmpty(picWidth))
|
|
|
- return null;
|
|
|
-
|
|
|
- if (X_UPYUN_WIDTH.equals(key))
|
|
|
- return picWidth;
|
|
|
- if (X_UPYUN_HEIGHT.equals(key))
|
|
|
- return picHeight;
|
|
|
- if (X_UPYUN_FRAMES.equals(key))
|
|
|
- return picFrames;
|
|
|
- if (X_UPYUN_FILE_TYPE.equals(key))
|
|
|
- return picType;
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 对字符串进行 MD5 加密
|
|
|
*
|
|
@@ -828,191 +517,6 @@ public class UpYunClient {
|
|
|
return "UpYun " + userName + ":" + md5(sign);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 连接处理逻辑
|
|
|
- *
|
|
|
- * @param method
|
|
|
- * 请求方式 {GET, POST, PUT, DELETE}
|
|
|
- * @param uri
|
|
|
- * 请求地址
|
|
|
- * @return 请求结果(字符串)或 null
|
|
|
- */
|
|
|
- private String HttpAction(String method, String uri) {
|
|
|
- return HttpAction(method, uri, null, null, false);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 连接处理逻辑
|
|
|
- *
|
|
|
- * @param method
|
|
|
- * 请求方式 {GET, POST, PUT, DELETE}
|
|
|
- * @param uri
|
|
|
- * 请求地址
|
|
|
- * @param datas
|
|
|
- * 该请求所需发送数据(可为 null)
|
|
|
- * @param outFile
|
|
|
- * 文件描述符(可为 null)
|
|
|
- * @param auto
|
|
|
- * 自动创建父级目录(最多10级)
|
|
|
- * @return 请求结果(字符串)或 null
|
|
|
- */
|
|
|
- private String HttpAction(String method, String uri, byte[] datas, File outFile, boolean auto) {
|
|
|
-
|
|
|
- return HttpAction(method, uri, datas, outFile, auto, null);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 连接处理逻辑
|
|
|
- *
|
|
|
- * @param method
|
|
|
- * 请求方式 {GET, POST, PUT, DELETE}
|
|
|
- * @param uri
|
|
|
- * 请求地址
|
|
|
- * @param datas
|
|
|
- * 该请求所需发送数据(可为 null)
|
|
|
- * @param outFile
|
|
|
- * 文件描述符(可为 null)
|
|
|
- * @param auto
|
|
|
- * 自动创建父级目录(最多10级)
|
|
|
- * @param params
|
|
|
- * 额外参数
|
|
|
- * @return 请求结果(字符串)或 null
|
|
|
- */
|
|
|
- private String HttpAction(String method, String uri, byte[] datas, File outFile, boolean auto,
|
|
|
- Map<String, String> params) {
|
|
|
-
|
|
|
- String result = null;
|
|
|
-
|
|
|
- HttpURLConnection conn = null;
|
|
|
- OutputStream os = null;
|
|
|
- InputStream is = null;
|
|
|
-
|
|
|
- try {
|
|
|
- // 获取链接
|
|
|
- URL url = new URL("http://" + apiDomain + uri);
|
|
|
- conn = (HttpURLConnection) url.openConnection();
|
|
|
-
|
|
|
- // 设置必要参数
|
|
|
- conn.setConnectTimeout(timeout);
|
|
|
- conn.setRequestMethod(method);
|
|
|
- conn.setUseCaches(false);
|
|
|
- if (!method.equals(METHOD_DELETE) && !method.equals(METHOD_HEAD)
|
|
|
- && !method.equals(METHOD_GET)) {
|
|
|
- conn.setDoOutput(true);
|
|
|
- }
|
|
|
-
|
|
|
- String date = getGMTDate();
|
|
|
-
|
|
|
- // 设置时间
|
|
|
- conn.setRequestProperty(DATE, date);
|
|
|
- conn.setRequestProperty("User-Agent", UpYunUtils.VERSION);
|
|
|
-
|
|
|
- // 是否自动创建父级目录
|
|
|
- if (auto) {
|
|
|
- conn.setRequestProperty(MKDIR, "true");
|
|
|
- }
|
|
|
-
|
|
|
- @SuppressWarnings("unused")
|
|
|
- long contentLength = 0;
|
|
|
-
|
|
|
- if (datas == null) {
|
|
|
- conn.setRequestProperty(CONTENT_LENGTH, "0");
|
|
|
- } else {
|
|
|
- contentLength = datas.length;
|
|
|
- conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(datas.length));
|
|
|
-
|
|
|
- // 设置文件的 MD5 参数
|
|
|
- if (!isEmpty(this.contentMD5)) {
|
|
|
- conn.setRequestProperty(CONTENT_MD5, this.contentMD5);
|
|
|
- }
|
|
|
- // 设置文件的访问密钥
|
|
|
- if (!isEmpty(this.fileSecret)) {
|
|
|
- conn.setRequestProperty(CONTENT_SECRET, this.fileSecret);
|
|
|
- this.fileSecret = null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 设置签名
|
|
|
- // conn.setRequestProperty(AUTHORIZATION,
|
|
|
- // sign(conn, uri, contentLength));
|
|
|
-
|
|
|
- conn.setRequestProperty(AUTHORIZATION,
|
|
|
- UpYunUtils.sign(method, date, uri, userName, password, contentMD5));
|
|
|
- this.contentMD5 = null;
|
|
|
- // 是否是创建文件目录
|
|
|
- boolean isFolder = false;
|
|
|
-
|
|
|
- // 设置额外的参数,如图片缩略图等
|
|
|
- if (params != null && !params.isEmpty()) {
|
|
|
-
|
|
|
- isFolder = !isEmpty(params.get(PARAMS.KEY_MAKE_DIR.getValue()));
|
|
|
-
|
|
|
- for (Map.Entry<String, String> param : params.entrySet()) {
|
|
|
- conn.setRequestProperty(param.getKey(), param.getValue());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 创建链接
|
|
|
- conn.connect();
|
|
|
-
|
|
|
- if (datas != null) {
|
|
|
- os = conn.getOutputStream();
|
|
|
- os.write(datas);
|
|
|
- os.flush();
|
|
|
- }
|
|
|
-
|
|
|
- if (isFolder) {
|
|
|
- os = conn.getOutputStream();
|
|
|
- os.flush();
|
|
|
- }
|
|
|
-
|
|
|
- if (outFile == null) {
|
|
|
-
|
|
|
- result = getText(conn, METHOD_HEAD.equals(method));
|
|
|
-
|
|
|
- } else {
|
|
|
- result = "";
|
|
|
-
|
|
|
- os = new FileOutputStream(outFile);
|
|
|
- byte[] data = new byte[4096];
|
|
|
- int temp = 0;
|
|
|
-
|
|
|
- is = conn.getInputStream();
|
|
|
-
|
|
|
- while ((temp = is.read(data)) != -1) {
|
|
|
- os.write(data, 0, temp);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- if (debug)
|
|
|
- e.printStackTrace();
|
|
|
-
|
|
|
- // 操作失败
|
|
|
- return null;
|
|
|
- } finally {
|
|
|
-
|
|
|
- try {
|
|
|
- if (os != null) {
|
|
|
- os.close();
|
|
|
- os = null;
|
|
|
- }
|
|
|
- if (is != null) {
|
|
|
- is.close();
|
|
|
- is = null;
|
|
|
- }
|
|
|
- } catch (IOException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
-
|
|
|
- if (conn != null) {
|
|
|
- conn.disconnect();
|
|
|
- conn = null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 获得连接请求的返回数据
|
|
|
*
|