国产成人精品亚洲777人妖,欧美日韩精品一区视频,最新亚洲国产,国产乱码精品一区二区亚洲

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Spring Boot項(xiàng)目中實(shí)現(xiàn)文件上傳功能的示例

瀏覽:140日期:2023-07-29 08:37:11

在實(shí)際項(xiàng)目中,文件上傳是很多項(xiàng)目必不可少的一個(gè)功能。那么在 Spring Boot 項(xiàng)目中又是如何來(lái)實(shí)現(xiàn)文件上傳功能的呢?一般來(lái)說(shuō),上傳的文件可以保存到項(xiàng)目根目錄下的某一文件夾中,但這樣做顯然是不太合適的。因此我們選擇將文件上傳到專(zhuān)門(mén)的文件服務(wù)器中。很多云計(jì)算廠商都提供文件存儲(chǔ)服務(wù)。這里我選擇的是阿里云的對(duì)象存儲(chǔ)(OSS)。

一、配置OSS1. 導(dǎo)入SDK

首先,你需要注冊(cè)阿里云的賬號(hào)并開(kāi)通對(duì)象存儲(chǔ)服務(wù)。在準(zhǔn)備工作完成之后,需要導(dǎo)入 JAVA 版本的 SDK,這里使用 maven 進(jìn)行導(dǎo)入

<!-- 阿里云OSS對(duì)象存儲(chǔ) --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.8.0</version></dependency>2. 修改配置文件

導(dǎo)入完成后在 application.properties 配置文件中添加以下內(nèi)容

# 節(jié)點(diǎn)域名aliyun.oss.endpoint=oss-cn-xxxxxxx.aliyuncs.com# 賬戶(hù)idaliyun.oss.accessKeyId=xxxxxxxxxxxxx# 賬戶(hù)密碼aliyun.oss.accessKeySecret=xxxxxxxxxxxxx# bucket名稱(chēng)aliyun.oss.bucketName=xxxxxxxxxxx# 簽名過(guò)期時(shí)間aliyun.oss.policy.expire=300# 上傳文件的最大尺寸aliyun.oss.maxSize=10# 上傳地址的前綴aliyun.oss.dir.prefix=xxx# 回調(diào)參數(shù)的請(qǐng)求地址aliyun.oss.callback=http://www.xxxxxx.com/api/aliyun/oss/callback

以上內(nèi)容在開(kāi)通服務(wù)后均可獲取到,請(qǐng)根據(jù)實(shí)際情況進(jìn)行修改

3. 初始化

OSSClient是OSS的Java客戶(hù)端,用于管理存儲(chǔ)空間和文件等OSS資源。使用Java SDK發(fā)起OSS請(qǐng)求,您需要初始化一個(gè)OSSClient實(shí)例,并根據(jù)需要修改ClientConfiguration的默認(rèn)配置項(xiàng)。

根據(jù)官方文檔的描述,需要初始化一個(gè)ossClient實(shí)例并將其注入到Spring容器中,因此可以編寫(xiě)一個(gè)配置類(lèi)OssConfig

@Configuration@PropertySource(value = {'classpath:application.properties'}, encoding = 'utf-8')public class OssConfig { @Value('${aliyun.oss.endpoint}') private String endpoint; @Value('${aliyun.oss.accessKeyId}') private String accessKeyId; @Value('${aliyun.oss.accessKeySecret}') private String secretAccessKey; @Bean public OSS ossClient(){ return new OSSClientBuilder().build(endpoint, accessKeyId, secretAccessKey); }}

更多詳細(xì)的配置,請(qǐng)參考官方文檔:初始化

二、文件上傳1. 流程分析

我們以典型的表單上傳為例,在使用對(duì)象存儲(chǔ)OSS后,表單上傳分為以下幾個(gè)流程:

Spring Boot項(xiàng)目中實(shí)現(xiàn)文件上傳功能的示例

注:Policy表單域用于驗(yàn)證請(qǐng)求的合法性。例如可以指定上傳的大小,可以指定上傳的Object名稱(chēng)等,上傳成功后客戶(hù)端跳轉(zhuǎn)到的URL,上傳成功后客戶(hù)端收到的狀態(tài)碼。

PolicyConditions policyConds = new PolicyConditions();policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, DIR_PREFIX);String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);// 將Policy字符串進(jìn)行base64編碼String policy = BinaryUtil.toBase64String(binaryData);// 用OSS的AccessKeySecret對(duì)base64編碼后的Policy進(jìn)行簽名String signature = ossClient.calculatePostSignature(postPolicy);

前端向OSS服務(wù)器上傳文件時(shí)要上傳Policy表單域,OSS服務(wù)器將對(duì)Policy表單域的內(nèi)容進(jìn)行驗(yàn)證。關(guān)于 Post Policy 的詳細(xì)內(nèi)容,請(qǐng)參考官方文檔:Post Policy

當(dāng)文件上傳成功后,OSS服務(wù)器會(huì)向應(yīng)用服務(wù)器發(fā)起回調(diào)請(qǐng)求,具體流程如下:

Spring Boot項(xiàng)目中實(shí)現(xiàn)文件上傳功能的示例

用戶(hù)只需要在發(fā)送給 OSS 的請(qǐng)求中攜帶相應(yīng)的 Callback 參數(shù),即能實(shí)現(xiàn)回調(diào)。

Callback 參數(shù)是由一段經(jīng)過(guò) base64 編碼的 JSON 字符串(字段)。構(gòu)建 callback 參數(shù)的關(guān)鍵是指定請(qǐng)求回調(diào)的服務(wù)器 URL(callbackUrl)以及回調(diào)的內(nèi)容(callbackBody)。

// 上傳回調(diào)參數(shù)Callback callback = new Callback();// 指定請(qǐng)求回調(diào)的服務(wù)器URLcallback.setCallbackUrl(CALLBACK);//(可選)設(shè)置回調(diào)請(qǐng)求消息頭中Host的值,即您的服務(wù)器配置Host的值。// callback.setCallbackHost('yourCallbackHost');// 設(shè)置發(fā)起回調(diào)時(shí)請(qǐng)求body的值。callback.setCallbackBody('{'filename':${object},'mineType':${mimeType}}');// 設(shè)置發(fā)起回調(diào)請(qǐng)求的Content-Type。callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);// 設(shè)置發(fā)起回調(diào)請(qǐng)求的自定義參數(shù),由Key和Value組成,Key必須以x:開(kāi)始。// callback.addCallbackVar('x:dir', 'value');

更詳細(xì)的內(nèi)容請(qǐng)閱讀官方文檔:Callback

2. 功能實(shí)現(xiàn)

首先編寫(xiě) Post Policy 封裝對(duì)象OssPolicyResult

@Datapublic class OssPolicyResult {@ApiModelProperty('用戶(hù)id')private String accessKeyId;@ApiModelProperty('Post Policy經(jīng)過(guò)base64編碼過(guò)的字符串') private String policy;@ApiModelProperty('對(duì)policy簽名后的字符串') private String signature;// @ApiModelProperty('對(duì)象的鍵值')// private String key;@ApiModelProperty('上傳文件夾路徑前綴') private String dir;@ApiModelProperty('oss對(duì)外服務(wù)的訪問(wèn)域名') private String host;@ApiModelProperty('上傳成功后的回調(diào)設(shè)置')private String callback;}

然后需自定義一個(gè)回調(diào)結(jié)果對(duì)象OssCallBackResult

@Datapublic class OssCallBackResult { @ApiModelProperty('文件的鏈接') private String url; @ApiModelProperty('文件名稱(chēng)') private String filename; @ApiModelProperty('文件大小') private String size; @ApiModelProperty('文件的mimeType') private String mimeType; @ApiModelProperty('圖片文件的寬') private String width; @ApiModelProperty('圖片文件的高') private String height;}

注:以上內(nèi)容可根據(jù)實(shí)際需要進(jìn)行修改

之后編寫(xiě) Service 接口及實(shí)現(xiàn)類(lèi)

Service 接口:

public interface OssService { // 生成Post PolicyOssPolicyResult policy(); // 上傳成功后的回調(diào)OssCallBackResult callback(Map<String, Object> requestBody);}

Service 實(shí)現(xiàn)類(lèi):

@Slf4j@Service@PropertySource(value = {'classpath:application.properties'}, encoding = 'utf-8')public class OssServiceImpl implements OssService {@Value('${aliyun.oss.endpoint}')private String ENDPOINT;@Value('${aliyun.oss.accessKeyId}')private String ACCESS_KEY_ID;@Value('${aliyun.oss.accessKeySecret}')private String SECRET_ACCESS_KEY;@Value('${aliyun.oss.bucketName}')private String BUCKET_NAME;@Value('${aliyun.oss.policy.expire}')private int EXPIRE;@Value('${aliyun.oss.maxSize}')private int MAX_SIZE;@Value('${aliyun.oss.dir.prefix}')private String DIR_PREFIX;@Value('${aliyun.oss.callback}')private String CALLBACK;@Autowiredprivate OSS ossClient;@Overridepublic OssPolicyResult policy() {OssPolicyResult result = new OssPolicyResult();// 簽名有效期long expireEndTime = System.currentTimeMillis() + EXPIRE * 1000;Date expiration = new Date(expireEndTime);// 文件名稱(chēng)// String filename = UUID.randomUUID().toString();// 文件大小long maxSize = MAX_SIZE * 1024 * 1024;// 提交節(jié)點(diǎn)String action = 'http://' + BUCKET_NAME + '.' + ENDPOINT;// 上傳回調(diào)參數(shù)Callback callback = new Callback();// 指定請(qǐng)求回調(diào)的服務(wù)器URLcallback.setCallbackUrl(CALLBACK);//(可選)設(shè)置回調(diào)請(qǐng)求消息頭中Host的值,即您的服務(wù)器配置Host的值。// callback.setCallbackHost('yourCallbackHost');// 設(shè)置發(fā)起回調(diào)時(shí)請(qǐng)求body的值。callback.setCallbackBody('{'filename':${object}}');// 設(shè)置發(fā)起回調(diào)請(qǐng)求的Content-Type。callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);// 設(shè)置發(fā)起回調(diào)請(qǐng)求的自定義參數(shù),由Key和Value組成,Key必須以x:開(kāi)始。// callback.addCallbackVar('x:dir', 'value');try {PolicyConditions policyConds = new PolicyConditions();policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, DIR_PREFIX);String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8); // 將Policy字符串進(jìn)行base64編碼String policy = BinaryUtil.toBase64String(binaryData); // 用OSS的AccessKeySecret對(duì)base64編碼后的Policy進(jìn)行簽名String signature = ossClient.calculatePostSignature(postPolicy); // 將callback配置進(jìn)行base64編碼String callbackData = BinaryUtil.toBase64String(OSSUtils.jsonizeCallback(callback).getBytes());// 返回結(jié)果result.setAccessKeyId(ACCESS_KEY_ID);result.setPolicy(policy);result.setSignature(signature);// result.setKey(filename);result.setDir(dir);result.setHost(action);result.setCallback(callbackData);} catch (Exception e) {log.error('簽名生成失敗', e);}return result;}@Overridepublic OssCallBackResult callback(Map<String, Object> requestBody) {OssCallBackResult ossCallbackResult = new OssCallBackResult();// 文件名String filename = requestBody.get('filename').toString();// 文件鏈接String url = 'https://' + BUCKET_NAME + '.' + ENDPOINT + '/' + DIR_PREFIX + '/' + filename;ossCallbackResult.setUrl(url);return ossCallbackResult;}}

添加 Controller 層:

@Api(tags = '阿里云對(duì)象存儲(chǔ)接口')@RequestMapping('/api')@RestControllerpublic class OssController {@Autowiredprivate OssService ossService;@ApiOperation(value = 'OSS上傳簽名生成')@GetMapping('/aliyun/oss/policy')public Object policy() {return ossService.policy();}@ApiOperation(value = 'OSS上傳成功回調(diào)')@PostMapping('/aliyun/oss/callback')public Object callback(@RequestBody Map<String, Object> requestBody) {return ossService.callback(requestBody);}}

到此這篇關(guān)于Spring Boot項(xiàng)目中實(shí)現(xiàn)文件上傳功能的示例的文章就介紹到這了,更多相關(guān)Spring Boot實(shí)現(xiàn)文件上傳內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 新民市| 东宁县| 龙陵县| 城口县| 凌海市| 佛坪县| 涞水县| 德州市| 平泉县| 六盘水市| 青冈县| 泰和县| 宁陵县| 武宣县| 枞阳县| 昭觉县| 东山县| 吕梁市| 岱山县| 龙山县| 和政县| 达日县| 射洪县| 霍邱县| 长汀县| 霍城县| 壶关县| 青海省| 辽宁省| 玉树县| 武义县| 象山县| 北辰区| 西藏| 洛川县| 沧州市| 彭泽县| 昆明市| 云梦县| 茂名市| 宁强县|