更正第三點:用戶帶着從服務器獲取的數據簽名和文件上傳到OSS,這樣做可以保證安全性、減輕服務器負擔。
1、操作步驟
①新建Bucket
②創建后更改跨域設置
這一步是保證跨域請胯下所有post請求都能訪問
③創建AccessKey
2、配置代碼
①參數講解
String accessId = "<yourAccessKeyId>"; // 請填寫您的AccessKeyId。 String accessKey = "<yourAccessKeySecret>"; // 請填寫您的AccessKeySecret。 String endpoint = "oss-cn-hangzhou.aliyuncs.com"; // 請填寫您的 endpoint。 String bucket = "bucket-name"; // 請填寫您的 bucketname 。 String host = "https://" + bucket + "." + endpoint; // host的格式為 bucketname.endpoint // callbackUrl為上傳回調服務器的URL,請將下面的IP和Port配置為您自己的真實信息。 String callbackUrl = "http://88.88.88.88:8888"; String dir = "user-dir-prefix/"; // 用戶上傳文件時指定的前綴。
②官方代碼樣例
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String accessId = "<yourAccessKeyId>"; // 請填寫您的AccessKeyId。 String accessKey = "<yourAccessKeySecret>"; // 請填寫您的AccessKeySecret。 String endpoint = "oss-cn-hangzhou.aliyuncs.com"; // 請填寫您的 endpoint。 String bucket = "bucket-name"; // 請填寫您的 bucketname 。 String host = "https://" + bucket + "." + endpoint; // host的格式為 bucketname.endpoint // callbackUrl為 上傳回調服務器的URL,請將下面的IP和Port配置為您自己的真實信息。 String callbackUrl = "http://88.88.88.88:8888"; String dir = "user-dir-prefix/"; // 用戶上傳文件時指定的前綴。 // 創建OSSClient實例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessId, accessKey); try { long expireTime = 30; long expireEndTime = System.currentTimeMillis() + expireTime * 1000; Date expiration = new Date(expireEndTime); // PostObject請求最大可支持的文件大小為5 GB,即CONTENT_LENGTH_RANGE為5*1024*1024*1024。 PolicyConditions policyConds = new PolicyConditions(); policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000); policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir); String postPolicy = ossClient.generatePostPolicy(expiration, policyConds); byte[] binaryData = postPolicy.getBytes("utf-8"); String encodedPolicy = BinaryUtil.toBase64String(binaryData); String postSignature = ossClient.calculatePostSignature(postPolicy); Map<String, String> respMap = new LinkedHashMap<String, String>(); respMap.put("accessid", accessId); respMap.put("policy", encodedPolicy); respMap.put("signature", postSignature); respMap.put("dir", dir); respMap.put("host", host); respMap.put("expire", String.valueOf(expireEndTime / 1000)); // respMap.put("expire", formatISO8601Date(expiration)); JSONObject jasonCallback = new JSONObject(); jasonCallback.put("callbackUrl", callbackUrl); jasonCallback.put("callbackBody", "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}"); jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded"); String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes()); respMap.put("callback", base64CallbackBody); JSONObject ja1 = JSONObject.fromObject(respMap); // System.out.println(ja1.toString()); response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET, POST"); response(request, response, ja1.toString()); } catch (Exception e) { // Assert.fail(e.getMessage()); System.out.println(e.getMessage()); } finally { ossClient.shutdown(); } }
③測試代碼
import com.aliyun.oss.OSSClient; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import javax.annotation.Resource; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; @SpringBootTest class GulimallThirdPartyApplicationTests { @Resource OSSClient ossClient; @Test public void testUplod() throws FileNotFoundException { // Endpoint以杭州為例,其它Region請按實際情況填寫。 String endpoint = "oss-cn-shenzhen.xxxx.com"; // 雲賬號AccessKey有所有API訪問權限,建議遵循阿里雲安全最佳實踐,創建並使用RAM子賬號進行API訪問或日常運維,請登錄 https://ram.console.aliyun.com 創建。 String accessKeyId = "xxxxxx"; // 請填寫您的AccessKeySecret。 String accessKeySecret = "xxxxxxx";// 請填寫您的AccessKeySecret // 創建OSSClient實例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // 上傳文件流。 InputStream inputStream = new FileInputStream("D:\\imgs\\a22.jpg");
// 上傳的Bucket 名稱和在Bucket中上傳圖片的新名稱。 ossClient.putObject("gulimall-lin", "house.jpg", inputStream); // 關閉OSSClient。 ossClient.shutdown(); System.out.println("上傳成功"); } @Test void contextLoads() { } }
運行發現文件上傳成功,存在圖片名稱:
3、實際代碼使用
①application.yml創建
spring:
cloud:
alicloud:
access-key: xxxxx //請填寫您的AccessKeySecret
secret-key: xxxxx // 請填寫您的AccessKeySecret
oss:
endpoint: oss-cn-shenzhen.xxxx.com // 請填寫您的EndPoint(地域節點)
bucket: gulimall-lin // 上傳的Bucket 名稱
application:
name: gulimall-third-party
server:
port: 30000
②應用服務器源碼包含了簽名直傳服務
package com.atguigu.gulimall.thirdparty.controller; import com.aliyun.oss.OSS; import com.aliyun.oss.common.utils.BinaryUtil; import com.aliyun.oss.model.MatchMode; import com.aliyun.oss.model.PolicyConditions; import com.atguigu.common.utils.R; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; @RestController public class OssController { @Resource OSS ossClient; @Value("${spring.cloud.alicloud.oss.endpoint}") private String endpoint; @Value("${spring.cloud.alicloud.oss.bucket}") private String bucket; @Value("${spring.cloud.alicloud.access-key}") private String accessId; @RequestMapping("/oss/policy") public R policy() { //host拼裝方式:ttps://gulimall-lin.oss-cn-shenzhen.aliyuncs.com/house.jpg // String bucket = "gulimall-lin"; // 請填寫您的 bucketname 。 String host = "https://" + bucket + "." + endpoint; // host的格式為 bucketname.endpoint // callbackUrl為 上傳回調服務器的URL,請將下面的IP和Port配置為您自己的真實信息。 //String callbackUrl = "http://88.88.88.88:8888"; String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());//以日期的方式創建文件夾放置當日上傳的文件 String dir = format+"/"; // 用戶上傳文件時指定的前綴。 Map<String, String> respMap = null; // 創建OSSClient實例。 try { long expireTime = 30; long expireEndTime = System.currentTimeMillis() + expireTime * 1000; Date expiration = new Date(expireEndTime); // PostObject請求最大可支持的文件大小為5 GB,即CONTENT_LENGTH_RANGE為5*1024*1024*1024。 PolicyConditions policyConds = new PolicyConditions(); policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000); policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir); String postPolicy = ossClient.generatePostPolicy(expiration, policyConds); byte[] binaryData = postPolicy.getBytes("utf-8"); String encodedPolicy = BinaryUtil.toBase64String(binaryData); String postSignature = ossClient.calculatePostSignature(postPolicy); respMap = new LinkedHashMap<String, String>(); respMap.put("accessid", accessId); respMap.put("policy", encodedPolicy); respMap.put("signature", postSignature); respMap.put("dir", dir); respMap.put("host", host); respMap.put("expire", String.valueOf(expireEndTime / 1000)); // respMap.put("expire", formatISO8601Date(expiration)); } catch (Exception e) { // Assert.fail(e.getMessage()); System.out.println(e.getMessage()); } finally { ossClient.shutdown(); } return R.ok().put("data",respMap); } }