|
@@ -1,438 +0,0 @@
|
|
|
-package cn.com.qmth.examcloud.web.filestorage;
|
|
|
-
|
|
|
-import java.io.DataInputStream;
|
|
|
-import java.io.DataOutputStream;
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.InputStream;
|
|
|
-import java.net.HttpURLConnection;
|
|
|
-import java.net.URL;
|
|
|
-
|
|
|
-import org.apache.commons.lang3.StringUtils;
|
|
|
-
|
|
|
-import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
|
-import cn.com.qmth.examcloud.commons.util.MD5;
|
|
|
-import cn.com.qmth.examcloud.web.aliyun.AliyunSiteManager;
|
|
|
-import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
|
|
|
-import cn.com.qmth.examcloud.web.support.SpringContextHolder;
|
|
|
-import cn.com.qmth.examcloud.web.upyun.UpyunSiteManager;
|
|
|
-
|
|
|
-public class FileStorageUtil {
|
|
|
-
|
|
|
- private static String fileStorageType = PropertyHolder.getString("$filestorage-type");
|
|
|
-
|
|
|
- private static String tempDir = PropertyHolder.getString("$filestorage-trans-tempdir");
|
|
|
-
|
|
|
- private static String beanSuff = "FileStorage";
|
|
|
-
|
|
|
- private static String connector = "://";
|
|
|
- /**
|
|
|
- * 根据当前配置存储类型保存文件到存储服务器
|
|
|
- *
|
|
|
- * @param siteId
|
|
|
- * @param env
|
|
|
- * @param in 文件流
|
|
|
- * @param md5 文件MD5 可为空
|
|
|
- * @return 返回包含协议名的地址,数据库直接存储用 如:upyun-1://student_photo/001.jpg
|
|
|
- */
|
|
|
- public static YunPathInfo saveFile(String siteId, FileStoragePathEnvInfo env, InputStream in,String md5) {
|
|
|
- FileStorageType fsType = FileStorageType.valueOf(fileStorageType);
|
|
|
- return saveFile(siteId, env, in, fsType,md5);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据当前配置存储类型保存文件到存储服务器
|
|
|
- *
|
|
|
- * @param siteId
|
|
|
- * @param env
|
|
|
- * @param file 文件
|
|
|
- * @param withMd5 是否校验MD5
|
|
|
- * @return 返回包含协议名的地址,数据库直接存储用 如:upyun-1://student_photo/001.jpg
|
|
|
- */
|
|
|
- public static YunPathInfo saveFile(String siteId, FileStoragePathEnvInfo env, File file,boolean withMd5) {
|
|
|
- FileStorageType fsType = FileStorageType.valueOf(fileStorageType);
|
|
|
- String md5 = null;
|
|
|
- if (withMd5) {
|
|
|
- md5 = MD5.md5Hex(file);
|
|
|
- }
|
|
|
- return saveFile(siteId, env, file, fsType,md5);
|
|
|
- }
|
|
|
- /**
|
|
|
- * 根据当前配置存储类型保存文件到存储服务器
|
|
|
- *
|
|
|
- * @param siteId
|
|
|
- * @param env
|
|
|
- * @param file 文件
|
|
|
- * @param md5 文件MD5 可为空
|
|
|
- * @return 返回包含协议名的地址,数据库直接存储用 如:upyun-1://student_photo/001.jpg
|
|
|
- */
|
|
|
- public static YunPathInfo saveFile(String siteId, FileStoragePathEnvInfo env, File file,String md5) {
|
|
|
- FileStorageType fsType = FileStorageType.valueOf(fileStorageType);
|
|
|
- return saveFile(siteId, env, file, fsType,md5);
|
|
|
- }
|
|
|
- /**
|
|
|
- * 根据存储类型保存文件到存储服务器
|
|
|
- *
|
|
|
- * @param siteId
|
|
|
- * @param env
|
|
|
- * @param in 文件流
|
|
|
- * @param fsType 存储类型
|
|
|
- * @param md5 文件MD5 可为空
|
|
|
- * @return 返回包含协议名的地址,数据库直接存储用 如:upyun-1://student_photo/001.jpg
|
|
|
- */
|
|
|
- private static YunPathInfo saveFile(String siteId, FileStoragePathEnvInfo env, InputStream in, FileStorageType fsType,String md5) {
|
|
|
-
|
|
|
- if (siteId == null) {
|
|
|
- throw new StatusException("1000", "siteId是空");
|
|
|
- }
|
|
|
- if (in == null) {
|
|
|
- throw new StatusException("1001", "文件流是空");
|
|
|
- }
|
|
|
- if (env == null) {
|
|
|
- throw new StatusException("1002", "文件上传路径信息是空");
|
|
|
- }
|
|
|
- env.setTimeMillis(String.valueOf(System.currentTimeMillis()));
|
|
|
- FileStorage fs = SpringContextHolder.getBean(fsType.name().toLowerCase() + beanSuff, FileStorage.class);
|
|
|
- return fs.saveFile(siteId, env, in,md5);
|
|
|
- }
|
|
|
- /**
|
|
|
- * 根据存储类型保存文件到存储服务器
|
|
|
- *
|
|
|
- * @param siteId
|
|
|
- * @param env
|
|
|
- * @param file 文件
|
|
|
- * @param fsType 存储类型
|
|
|
- * @param md5 文件MD5 可为空
|
|
|
- * @return 返回包含协议名的地址,数据库直接存储用 如:upyun-1://student_photo/001.jpg
|
|
|
- */
|
|
|
- private static YunPathInfo saveFile(String siteId, FileStoragePathEnvInfo env, File file, FileStorageType fsType,String md5) {
|
|
|
- if (siteId == null) {
|
|
|
- throw new StatusException("2000", "siteId是空");
|
|
|
- }
|
|
|
- if (file == null) {
|
|
|
- throw new StatusException("2001", "文件是空");
|
|
|
- }
|
|
|
- if (env == null) {
|
|
|
- throw new StatusException("2002", "文件上传路径信息是空");
|
|
|
- }
|
|
|
- env.setTimeMillis(String.valueOf(System.currentTimeMillis()));
|
|
|
- FileStorage fs = SpringContextHolder.getBean(fsType.name().toLowerCase() + beanSuff, FileStorage.class);
|
|
|
- return fs.saveFile(siteId, env, file,md5);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取文件访问路径
|
|
|
- *
|
|
|
- * @param path 数据库保存的路径 如:upyun-1://student_photo/001.jpg,兼容老数据,路径必须是包含根路径的
|
|
|
- * @return 可直接访问的文件地址
|
|
|
- */
|
|
|
- public static String realPath(String path) {
|
|
|
- if(StringUtils.isBlank(path)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- if (StringUtils.isBlank(path)) {
|
|
|
- throw new StatusException("3001", "文件路径是空");
|
|
|
- }
|
|
|
- // 兼容处理老数据文件路径
|
|
|
- path = diposeOldPath(path);
|
|
|
- // 如果是全路径直接返回
|
|
|
- if (path.startsWith("http") || path.startsWith("https")) {
|
|
|
- return path;
|
|
|
- }
|
|
|
- // 根据路径头获取对应的处理类
|
|
|
- FileStorage fs = SpringContextHolder.getBean(getHead(path).toLowerCase() + beanSuff, FileStorage.class);
|
|
|
- // 返回处理类处理结果
|
|
|
- return fs.realPath(path);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 将文件转换到指定存储服务上
|
|
|
- *
|
|
|
- * @param path 数据库保存的路径
|
|
|
- * 如:upyun-1://student_photo/001.jpg,兼容老数据,路径必须是包含根路径的
|
|
|
- * @param transFsType 要转换的类型
|
|
|
- * @return 转换之后的路径
|
|
|
- */
|
|
|
- public static String transPath(String path, FileStorageType transFsType) {
|
|
|
-
|
|
|
- File file = null;
|
|
|
- if (StringUtils.isBlank(path)) {
|
|
|
- throw new StatusException("4001", "文件路径是空");
|
|
|
- }
|
|
|
- if (transFsType == null) {
|
|
|
- throw new StatusException("4002", "转换类型是空");
|
|
|
- }
|
|
|
- // 兼容处理老数据文件路径
|
|
|
- path = diposeOldPath(path);
|
|
|
- // 如果是全路径直接返回
|
|
|
- if (path.startsWith("http") || path.startsWith("https")) {
|
|
|
- return path;
|
|
|
- }
|
|
|
-
|
|
|
- FileStorageType sourseType = FileStorageType.valueOf(getHead(path));
|
|
|
- // 相同的类型直接返回
|
|
|
- if (sourseType.equals(transFsType)) {
|
|
|
- return path;
|
|
|
- }
|
|
|
- // 获取对应的处理类
|
|
|
- FileStorage fs = SpringContextHolder.getBean(transFsType.name().toLowerCase() + beanSuff, FileStorage.class);
|
|
|
- try {
|
|
|
- // 下载文件到本地
|
|
|
- String httppath = fs.realPath(getPath(path));
|
|
|
- file = downFile(httppath);
|
|
|
- // 保存文件到指定存储服务器,并返回路径
|
|
|
- YunPathInfo ret = fs.saveFile(file, "from" + sourseType.name().toLowerCase() + "/" + getPath(path));
|
|
|
- return ret.getRelativePath();
|
|
|
- } catch (IOException e) {
|
|
|
- throw new StatusException("4003", "下载文件出错 " + e.getMessage());
|
|
|
- } finally {
|
|
|
- if (file != null) {
|
|
|
- file.delete();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- private static File downFile(String url) throws IOException {
|
|
|
- String name = url.substring(url.lastIndexOf("/") + 1);
|
|
|
- File file = new File(tempDir + "/" + name);
|
|
|
- if (file.exists()) {
|
|
|
- file.delete();
|
|
|
- }
|
|
|
- file.createNewFile();
|
|
|
- saveUrlAs(url, file.getAbsolutePath());
|
|
|
- return file;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @param path 数据库存储的路径。路径必须是包含根路径的
|
|
|
- * @return 处理后的路径。补全路径头。
|
|
|
- */
|
|
|
- private static String diposeOldPath(String path) {
|
|
|
- if(StringUtils.isBlank(path)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- // 如果是全路径直接返回
|
|
|
- if (path.startsWith("http") || path.startsWith("https")) {
|
|
|
- return path;
|
|
|
- }
|
|
|
- // 如果是半路径,转换成又拍云类型
|
|
|
- if (path.indexOf(":") == -1) {
|
|
|
- if (path.startsWith("/")) {
|
|
|
- path = path.substring(1);
|
|
|
- }
|
|
|
- return FileStorageType.UPYUN.name().toLowerCase() +"-1"+ connector + path;
|
|
|
- }
|
|
|
- // 无需处理
|
|
|
- return path;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- public static String getUrl(String domain, String path) {
|
|
|
- if(StringUtils.isBlank(domain)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- if(StringUtils.isBlank(path)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- if (path.startsWith("/")) {
|
|
|
- path = path.substring(1);
|
|
|
- }
|
|
|
- if (domain.endsWith("/")) {
|
|
|
- domain = domain.substring(0, domain.length());
|
|
|
- }
|
|
|
- return domain + "/" + path;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 将网络文件保存到本地
|
|
|
- *
|
|
|
- * @param fileUrl 网络文件URL
|
|
|
- * @param localFilePath 例如D:/123.txt
|
|
|
- * @throws IOException
|
|
|
- */
|
|
|
- private static void saveUrlAs(String fileUrl, String localFilePath) throws IOException {
|
|
|
- URL url = new URL(fileUrl);
|
|
|
-
|
|
|
- HttpURLConnection connection;
|
|
|
- connection = (HttpURLConnection) url.openConnection();
|
|
|
-
|
|
|
- try (DataInputStream dataInputStream = new DataInputStream(connection.getInputStream());
|
|
|
- FileOutputStream fileOutputStream = new FileOutputStream(localFilePath);
|
|
|
- DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);) {
|
|
|
-
|
|
|
- byte[] buffer = new byte[4096];
|
|
|
- int count;
|
|
|
- while ((count = dataInputStream.read(buffer)) > 0) {
|
|
|
- dataOutputStream.write(buffer, 0, count);
|
|
|
- }
|
|
|
- fileOutputStream.flush();
|
|
|
- dataOutputStream.flush();
|
|
|
- } finally {
|
|
|
- if (connection != null) {
|
|
|
- connection.disconnect();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- /**将网络文件保存到本地
|
|
|
- * @param fileUrl 网络文件URL
|
|
|
- * @param localFile 本地文件对象
|
|
|
- * @throws IOException
|
|
|
- */
|
|
|
- public static void saveUrlAs(String fileUrl, File localFile) {
|
|
|
- try {
|
|
|
- saveUrlAs(fileUrl, localFile.getAbsolutePath());
|
|
|
- } catch (IOException e) {
|
|
|
- throw new StatusException("5001", "下载文件出错",e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**获取指定云存储的签名
|
|
|
- * @param siteId
|
|
|
- * @param env
|
|
|
- * @param md5
|
|
|
- * @return
|
|
|
- */
|
|
|
- public static YunHttpRequest getSignature(FileStorageType fsType,String siteId, FileStoragePathEnvInfo env, String md5) {
|
|
|
- env.setTimeMillis(String.valueOf(System.currentTimeMillis()));
|
|
|
- // 获取对应的处理类
|
|
|
- FileStorage fs = SpringContextHolder.getBean(fsType.name().toLowerCase() + beanSuff, FileStorage.class);
|
|
|
- return fs.getSignature(siteId, env, md5);
|
|
|
- }
|
|
|
-
|
|
|
- public static String getFileStorageType() {
|
|
|
- return fileStorageType;
|
|
|
- }
|
|
|
-
|
|
|
- /**获取完整的不带域名的路径
|
|
|
- * @param prefixPath 路径前缀
|
|
|
- * @param sourcePath 数据库存储的路径
|
|
|
- * @return 处理之后的路径
|
|
|
- */
|
|
|
- public static String getIntactPath(String prefixPath,String sourcePath) {
|
|
|
- if(StringUtils.isBlank(sourcePath)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- // 如果是全路径直接返回
|
|
|
- if (sourcePath.startsWith("http") || sourcePath.startsWith("https")) {
|
|
|
- return sourcePath;
|
|
|
- }
|
|
|
- // 如果是半路径则拼接
|
|
|
- if (sourcePath.indexOf(":") == -1) {
|
|
|
- if (sourcePath.startsWith("/")) {
|
|
|
- sourcePath = sourcePath.substring(1);
|
|
|
- }
|
|
|
- if (prefixPath.endsWith("/")) {
|
|
|
- prefixPath = prefixPath.substring(0,prefixPath.length());
|
|
|
- }
|
|
|
- return prefixPath+"/"+sourcePath;
|
|
|
- }
|
|
|
- // 新协议无需处理
|
|
|
- return sourcePath;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**删除云存储文件
|
|
|
- * @param path 全路径,包含根目录,含协议名
|
|
|
- */
|
|
|
- public static void deleteFile(String path) {
|
|
|
- if(StringUtils.isBlank(path)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- path=diposeOldPath(path);
|
|
|
- // 如果是全路径直接返回
|
|
|
- if (path.startsWith("http") || path.startsWith("https")) {
|
|
|
- return;
|
|
|
- }
|
|
|
- FileStorage fs = SpringContextHolder.getBean(getHead(path).toLowerCase() + beanSuff, FileStorage.class);
|
|
|
- fs.deleteFile(path);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取文件访问路径(备用域名地址)
|
|
|
- *
|
|
|
- * @param path 数据库保存的路径 如:upyun-1://student_photo/001.jpg,兼容老数据,路径必须是包含根路径的
|
|
|
- * @return 可直接访问的文件地址,如果没有配置备用地址,则返回主域名地址
|
|
|
- */
|
|
|
- public static String realPathBackup(String path) {
|
|
|
- if(StringUtils.isBlank(path)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- if (StringUtils.isBlank(path)) {
|
|
|
- throw new StatusException("6001", "文件路径是空");
|
|
|
- }
|
|
|
- // 兼容处理老数据文件路径
|
|
|
- path = diposeOldPath(path);
|
|
|
- // 如果是全路径直接返回
|
|
|
- if (path.startsWith("http") || path.startsWith("https")) {
|
|
|
- return path;
|
|
|
- }
|
|
|
- // 根据路径头获取对应的处理类
|
|
|
- FileStorage fs = SpringContextHolder.getBean(getHead(path).toLowerCase() + beanSuff, FileStorage.class);
|
|
|
- // 返回处理类处理结果
|
|
|
- return fs.realPathBackup(path);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- public static String getYunId(String path) {
|
|
|
- if(StringUtils.isBlank(path)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- if(path.indexOf(connector)==-1) {
|
|
|
- throw new StatusException("7001", "文件路径格式错误:"+path);
|
|
|
- }
|
|
|
- String hpath = path.substring(0, path.indexOf(connector));
|
|
|
- if(hpath.indexOf("-") ==-1) {
|
|
|
- throw new StatusException("7002", "文件路径格式错误:"+path);
|
|
|
- }
|
|
|
- String yunId = hpath.substring(hpath.indexOf("-") + 1);
|
|
|
- if(StringUtils.isBlank(yunId)) {
|
|
|
- throw new StatusException("7003", "文件路径格式错误:"+path);
|
|
|
- }
|
|
|
- return yunId;
|
|
|
- }
|
|
|
-
|
|
|
- public static String getHead(String path) {
|
|
|
- if(StringUtils.isBlank(path)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- if(path.indexOf(connector)==-1) {
|
|
|
- throw new StatusException("8001", "文件路径格式错误:"+path);
|
|
|
- }
|
|
|
- String hpath = path.substring(0, path.indexOf(connector));
|
|
|
- if(hpath.indexOf("-") ==-1) {
|
|
|
- throw new StatusException("8002", "文件路径格式错误:"+path);
|
|
|
- }
|
|
|
- String head = hpath.substring(0, hpath.indexOf("-"));
|
|
|
- if(StringUtils.isBlank(head)) {
|
|
|
- throw new StatusException("8003", "文件路径格式错误:"+path);
|
|
|
- }
|
|
|
- return head;
|
|
|
- }
|
|
|
-
|
|
|
- public static String getPath(String path) {
|
|
|
- if(StringUtils.isBlank(path)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- if(path.indexOf(connector)==-1) {
|
|
|
- throw new StatusException("9001", "文件路径格式错误:"+path);
|
|
|
- }
|
|
|
- String rpath = path.substring(path.indexOf(connector) + 3);
|
|
|
- if(StringUtils.isBlank(rpath)) {
|
|
|
- throw new StatusException("9002", "文件路径格式错误:"+path);
|
|
|
- }
|
|
|
- return rpath;
|
|
|
- }
|
|
|
- public static void initYunClient() {
|
|
|
- UpyunSiteManager.initClient();
|
|
|
- AliyunSiteManager.initClient();
|
|
|
- }
|
|
|
- public static void initYunSite() {
|
|
|
- UpyunSiteManager.initSite();
|
|
|
- AliyunSiteManager.initSite();
|
|
|
- }
|
|
|
-
|
|
|
-}
|