Przeglądaj źródła

阿里云签名

xiatian 5 lat temu
rodzic
commit
74e3c30527

+ 8 - 0
src/main/java/cn/com/qmth/examcloud/web/filestorage/FileStorage.java

@@ -24,4 +24,12 @@ public interface FileStorage {
 	 */
 	public String saveFile(File file, String path);
 	
+	/**获取云存储签名
+	 * @param siteId
+	 * @param env
+	 * @param md5
+	 * @return
+	 */
+	public YunHttpRequest  getSignature(String siteId,FileStoragePathEnvInfo env,String md5);
+	
 }

+ 47 - 24
src/main/java/cn/com/qmth/examcloud/web/filestorage/FileStorageUtil.java

@@ -24,32 +24,36 @@ public class FileStorageUtil {
 
 	private static String connector = "://";
 
-	/**根据当前配置存储类型保存文件到存储服务器
+	/**
+	 * 根据当前配置存储类型保存文件到存储服务器
+	 * 
 	 * @param siteId
 	 * @param env
-	 * @param file 文件
-	 * @return 返回包含协议名的地址,数据库直接存储用  如:upyun-1://student_photo/001.jpg
+	 * @param file   文件
+	 * @return 返回包含协议名的地址,数据库直接存储用 如:upyun-1://student_photo/001.jpg
 	 */
-	public static String saveFile(String siteId,FileStoragePathEnvInfo env,File file) {
+	public static String saveFile(String siteId, FileStoragePathEnvInfo env, File file) {
 		FileStorageType fsType = FileStorageType.valueOf(fileStorageType);
 		return saveFile(siteId, env, file, fsType);
 	}
 
-	/**根据存储类型保存文件到存储服务器
+	/**
+	 * 根据存储类型保存文件到存储服务器
+	 * 
 	 * @param siteId
 	 * @param env
-	 * @param file 文件
+	 * @param file   文件
 	 * @param fsType 存储类型
-	 * @return 返回包含协议名的地址,数据库直接存储用  如:upyun-1://student_photo/001.jpg
+	 * @return 返回包含协议名的地址,数据库直接存储用 如:upyun-1://student_photo/001.jpg
 	 */
-	private static String saveFile(String siteId,FileStoragePathEnvInfo env,File file, FileStorageType fsType) {
+	private static String saveFile(String siteId, FileStoragePathEnvInfo env, File file, FileStorageType fsType) {
 		if (siteId == null) {
 			throw new StatusException("2000", "siteId是空");
 		}
 		if (file == null) {
 			throw new StatusException("2001", "文件是空");
 		}
-		if (env==null) {
+		if (env == null) {
 			throw new StatusException("2002", "文件上传路径信息是空");
 		}
 		FileStorage fs = SpringContextHolder.getBean(fsType.name().toLowerCase() + beanSuff, FileStorage.class);
@@ -83,7 +87,8 @@ public class FileStorageUtil {
 	/**
 	 * 将文件转换到指定存储服务上
 	 * 
-	 * @param path        数据库保存的路径 如:upyun-1://student_photo/001.jpg,兼容老数据,路径必须是包含根路径的
+	 * @param path        数据库保存的路径
+	 *                    如:upyun-1://student_photo/001.jpg,兼容老数据,路径必须是包含根路径的
 	 * @param transFsType 要转换的类型
 	 * @return 转换之后的路径
 	 */
@@ -114,10 +119,10 @@ public class FileStorageUtil {
 			String httppath = fs.realPath(getPath(path));
 			file = downFile(httppath);
 			// 保存文件到指定存储服务器,并返回路径
-			String ret = fs.saveFile(file, "from"+sourseType.name().toLowerCase()+"/"+getPath(path));
+			String ret = fs.saveFile(file, "from" + sourseType.name().toLowerCase() + "/" + getPath(path));
 			return ret;
 		} catch (IOException e) {
-			throw new StatusException("4003", "下载文件出错 "+e.getMessage());
+			throw new StatusException("4003", "下载文件出错 " + e.getMessage());
 		} finally {
 			if (file != null) {
 				file.delete();
@@ -127,9 +132,9 @@ public class FileStorageUtil {
 	}
 
 	private static File downFile(String url) throws IOException {
-		String name=url.substring(url.lastIndexOf("/")+1);
-		File file=new File(tempDir+"/"+name);
-		if(file.exists()) {
+		String name = url.substring(url.lastIndexOf("/") + 1);
+		File file = new File(tempDir + "/" + name);
+		if (file.exists()) {
 			file.delete();
 		}
 		file.createNewFile();
@@ -156,15 +161,15 @@ public class FileStorageUtil {
 		// 无需处理
 		return path;
 	}
-	
+
 	public static String getYunId(String path) {
-		String hpath = path.substring(0,path.indexOf(connector));
-		String yunId = hpath.substring(path.indexOf("-")+1);
+		String hpath = path.substring(0, path.indexOf(connector));
+		String yunId = hpath.substring(path.indexOf("-") + 1);
 		return yunId;
 	}
-	
+
 	public static String getHead(String path) {
-		String hpath = path.substring(0,path.indexOf(connector));
+		String hpath = path.substring(0, path.indexOf(connector));
 		String head = hpath.substring(0, hpath.indexOf("-"));
 		return head;
 	}
@@ -173,15 +178,15 @@ public class FileStorageUtil {
 		String rpath = path.substring(path.indexOf(connector) + 4);
 		return rpath;
 	}
-	
-	public static String getUrl(String domain,String path) {
+
+	public static String getUrl(String domain, String path) {
 		if (path.startsWith("/")) {
 			path = path.substring(1);
 		}
 		if (domain.endsWith("/")) {
-			domain = domain.substring(0,domain.length());
+			domain = domain.substring(0, domain.length());
 		}
-		return domain+"/"+path;
+		return domain + "/" + path;
 	}
 
 	/**
@@ -215,4 +220,22 @@ public class FileStorageUtil {
 			}
 		}
 	}
+
+	/**获取指定云存储的签名
+	 * @param siteId
+	 * @param env
+	 * @param md5
+	 * @return
+	 */
+	public static YunHttpRequest getSignature(FileStorageType fsType,String siteId, FileStoragePathEnvInfo env, String md5) {
+		// 获取对应的处理类
+		FileStorage fs = SpringContextHolder.getBean(fsType.name().toLowerCase() + beanSuff, FileStorage.class);
+		return fs.getSignature(siteId, env, md5);
+	}
+
+	public static String getFileStorageType() {
+		return fileStorageType;
+	}
+	
+	
 }

+ 45 - 0
src/main/java/cn/com/qmth/examcloud/web/filestorage/YunHttpRequest.java

@@ -0,0 +1,45 @@
+package cn.com.qmth.examcloud.web.filestorage;
+
+import java.util.Map;
+
+import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
+
+public class YunHttpRequest implements JsonSerializable {
+
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -6298376638986327265L;
+
+	private String accessUrl;
+
+	private String formUrl;
+
+	private Map<String, String> formParams;
+
+	public String getAccessUrl() {
+		return accessUrl;
+	}
+
+	public void setAccessUrl(String accessUrl) {
+		this.accessUrl = accessUrl;
+	}
+
+	public String getFormUrl() {
+		return formUrl;
+	}
+
+	public void setFormUrl(String formUrl) {
+		this.formUrl = formUrl;
+	}
+
+	public Map<String, String> getFormParams() {
+		return formParams;
+	}
+
+	public void setFormParams(Map<String, String> formParams) {
+		this.formParams = formParams;
+	}
+
+}

+ 75 - 25
src/main/java/cn/com/qmth/examcloud/web/filestorage/impl/AliyunFileStorageImpl.java

@@ -10,6 +10,7 @@ import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -17,11 +18,15 @@ import java.util.Map;
 
 import javax.activation.MimetypesFileTypeMap;
 
+import org.apache.commons.lang3.time.DateUtils;
 import org.springframework.stereotype.Service;
 
+import com.google.common.collect.Maps;
+
 import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
 import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
+import cn.com.qmth.examcloud.commons.util.DateUtil;
 import cn.com.qmth.examcloud.commons.util.FreeMarkerUtil;
 import cn.com.qmth.examcloud.web.aliyun.AliYunAccount;
 import cn.com.qmth.examcloud.web.aliyun.AliyunSite;
@@ -30,37 +35,39 @@ import cn.com.qmth.examcloud.web.filestorage.FileStorage;
 import cn.com.qmth.examcloud.web.filestorage.FileStoragePathEnvInfo;
 import cn.com.qmth.examcloud.web.filestorage.FileStorageType;
 import cn.com.qmth.examcloud.web.filestorage.FileStorageUtil;
+import cn.com.qmth.examcloud.web.filestorage.YunHttpRequest;
 
 @Service(value = "aliyunFileStorage")
 public class AliyunFileStorageImpl implements FileStorage {
 	private ExamCloudLog log = ExamCloudLogFactory.getLog(this.getClass());
-	
+
 	// 文件最大大小(byte)
 	private static int maxFileSize = 100 * 1024 * 1024;
 
-
 	@Override
 	public String saveFile(File file, String path) {
 		try {
-			String siteId="transPath";
+			String siteId = "transPath";
 			FileStoragePathEnvInfo env = new FileStoragePathEnvInfo();
 			env.setRelativePath(path);
-			String relativePath=postObject(siteId, env, file, null);
-			AliyunSite as=AliyunSiteManager.getAliyunSite(siteId);
-			return FileStorageType.ALIYUN+"-"+as.getAliyunId()+"://"+relativePath;
+			String relativePath = postObject(siteId, env, file, null);
+			AliyunSite as = AliyunSiteManager.getAliyunSite(siteId);
+			return FileStorageType.ALIYUN + "-" + as.getAliyunId() + "://" + relativePath;
 		} catch (IOException e) {
-			throw new StatusException("1001", "上传出错",e);
+			throw new StatusException("1001", "上传出错", e);
 		}
 	}
 
 	@Override
 	public String realPath(String path) {
-		String yunId=FileStorageUtil.getYunId(path);
-		AliYunAccount ac=AliyunSiteManager.getAliYunAccountByAliyunId(yunId);
+		String yunId = FileStorageUtil.getYunId(path);
+		AliYunAccount ac = AliyunSiteManager.getAliYunAccountByAliyunId(yunId);
 		return FileStorageUtil.getUrl(ac.getDomain(), path);
 	}
 
-	/**表单上传
+	/**
+	 * 表单上传
+	 * 
 	 * @param siteId
 	 * @param env
 	 * @param file
@@ -68,19 +75,19 @@ public class AliyunFileStorageImpl implements FileStorage {
 	 * @return 不带域名的完整路径
 	 * @throws IOException
 	 */
-	private  String  postObject(String siteId, FileStoragePathEnvInfo env,File file,String md5) throws IOException {
-		AliyunSite as=AliyunSiteManager.getAliyunSite(siteId);
-		AliYunAccount ac=AliyunSiteManager.getAliYunAccountByAliyunId(as.getAliyunId());
-		String ossEndpoint=ac.getOssEndpoint();
-		String bucket=ac.getBucket();
-		String accessKeyId=ac.getAccessKeyId();
-		String accessKeySecret=ac.getAccessKeySecret();
-		//阿里云文件路径
+	private String postObject(String siteId, FileStoragePathEnvInfo env, File file, String md5) throws IOException {
+		AliyunSite as = AliyunSiteManager.getAliyunSite(siteId);
+		AliYunAccount ac = AliyunSiteManager.getAliYunAccountByAliyunId(as.getAliyunId());
+		String ossEndpoint = ac.getOssEndpoint();
+		String bucket = ac.getBucket();
+		String accessKeyId = ac.getAccessKeyId();
+		String accessKeySecret = ac.getAccessKeySecret();
+		// 阿里云文件路径
 		String path = FreeMarkerUtil.process(as.getPath(), env);
 		if (path.startsWith("/")) {
 			path = path.substring(1);
 		}
-		
+
 		String filepath = file.getAbsolutePath();
 		String filename = path.substring(path.lastIndexOf("/") + 1);
 		String urlStr = ossEndpoint.replace("http://", "http://" + bucket + "."); // 提交表单的URL为bucket域名
@@ -106,12 +113,13 @@ public class AliyunFileStorageImpl implements FileStorage {
 		fileMap.put("file", filepath);
 
 		String ret = formUpload(urlStr, textMap, fileMap);
-		log.info("oss上传:"+ret);
+		log.info("oss上传:" + ret);
 		return path;
 	}
 
 	@SuppressWarnings("rawtypes")
-	private static String formUpload(String urlStr, Map<String, String> textMap, Map<String, String> fileMap) throws IOException {
+	private static String formUpload(String urlStr, Map<String, String> textMap, Map<String, String> fileMap)
+			throws IOException {
 		String res = "";
 		HttpURLConnection conn = null;
 		String BOUNDARY = "9431149156168";
@@ -219,11 +227,53 @@ public class AliyunFileStorageImpl implements FileStorage {
 	@Override
 	public String saveFile(String siteId, FileStoragePathEnvInfo env, File file) {
 		try {
-			String relativePath=postObject(siteId, env, file, null);
-			AliyunSite as=AliyunSiteManager.getAliyunSite(siteId);
-			return FileStorageType.ALIYUN+"-"+as.getAliyunId()+"://"+relativePath;
+			String relativePath = postObject(siteId, env, file, null);
+			AliyunSite as = AliyunSiteManager.getAliyunSite(siteId);
+			return FileStorageType.ALIYUN + "-" + as.getAliyunId() + "://" + relativePath;
 		} catch (IOException e) {
-			throw new StatusException("5001", "上传出错",e);
+			throw new StatusException("5001", "上传出错", e);
+		}
+	}
+
+	@Override
+	public YunHttpRequest getSignature(String siteId, FileStoragePathEnvInfo env, String md5) {
+		AliyunSite site = AliyunSiteManager.getAliyunSite(siteId);
+		AliYunAccount ac = AliyunSiteManager.getAliYunAccountByAliyunId(site.getAliyunId());
+		String ossEndpoint = ac.getOssEndpoint();
+		String bucket = ac.getBucket();
+		String accessKeyId = ac.getAccessKeyId();
+		String accessKeySecret = ac.getAccessKeySecret();
+		String urlStr = ossEndpoint.replace("http://", "http://" + bucket + ".");
+		env.setTimeMillis(String.valueOf(System.currentTimeMillis()));
+
+		String path = FreeMarkerUtil.process(site.getPath(), env);
+		if (path.startsWith("/")) {
+			path = path.substring(1);
 		}
+
+		String accessUrl = FileStorageUtil.getUrl(ac.getDomain(), path);
+
+		Map<String, String> params = Maps.newHashMap();
+		// key
+		params.put("key", path);
+		// OSSAccessKeyId
+		params.put("OSSAccessKeyId", accessKeyId);
+		// policy
+		Date expiration = DateUtils.addSeconds(new Date(), 600);
+		String expirationStr = DateUtil.format(expiration, "yyyy-MM-dd'T'HH:mm:ss.SSS Z");
+		String policy = "{\"expiration\": \"" + expirationStr + "\",\"conditions\": [[\"content-length-range\", 0, "
+				+ maxFileSize + "]]}";
+		String encodePolicy = java.util.Base64.getEncoder().encodeToString(policy.getBytes());
+		params.put("policy", encodePolicy);
+		// Signature
+		String signaturecom = com.aliyun.oss.common.auth.ServiceSignature.create().computeSignature(accessKeySecret,
+				encodePolicy);
+		params.put("Signature", signaturecom);
+
+		YunHttpRequest request = new YunHttpRequest();
+		request.setAccessUrl(accessUrl);
+		request.setFormParams(params);
+		request.setFormUrl(urlStr);
+		return request;
 	}
 }

+ 13 - 0
src/main/java/cn/com/qmth/examcloud/web/filestorage/impl/UpyunFileStorageImpl.java

@@ -9,7 +9,9 @@ import cn.com.qmth.examcloud.web.filestorage.FileStorage;
 import cn.com.qmth.examcloud.web.filestorage.FileStoragePathEnvInfo;
 import cn.com.qmth.examcloud.web.filestorage.FileStorageType;
 import cn.com.qmth.examcloud.web.filestorage.FileStorageUtil;
+import cn.com.qmth.examcloud.web.filestorage.YunHttpRequest;
 import cn.com.qmth.examcloud.web.upyun.UpYunClient;
+import cn.com.qmth.examcloud.web.upyun.UpYunHttpRequest;
 import cn.com.qmth.examcloud.web.upyun.UpYunPathInfo;
 import cn.com.qmth.examcloud.web.upyun.UpyunPathEnvironmentInfo;
 import cn.com.qmth.examcloud.web.upyun.UpyunService;
@@ -61,4 +63,15 @@ public class UpyunFileStorageImpl implements FileStorage {
 		ret.setUserId(env.getUserId());
 		return ret;
 	}
+
+	@Override
+	public YunHttpRequest getSignature(String siteId, FileStoragePathEnvInfo env, String md5) {
+		UpYunHttpRequest req=upyunService.buildUpYunHttpRequest(siteId, of(env), md5);
+		YunHttpRequest ret=new YunHttpRequest();
+		ret.setAccessUrl(req.getAccessUrl());
+		ret.setFormParams(req.getFormParams());
+		ret.setFormUrl(req.getFormUrl());
+		return ret;
+	}
+
 }