欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2020年12月08日 11:41:54   作者:風(fēng)起青萍末  
這篇文章主要介紹了Spring Boot項(xiàng)目中實(shí)現(xiàn)文件上傳功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

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

一、配置OSS

1. 導(dǎo)入SDK

首先,你需要注冊(cè)阿里云的賬號(hào)并開通對(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
# 賬戶id
aliyun.oss.accessKeyId=xxxxxxxxxxxxx
# 賬戶密碼
aliyun.oss.accessKeySecret=xxxxxxxxxxxxx
# bucket名稱
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)容在開通服務(wù)后均可獲取到,請(qǐng)根據(jù)實(shí)際情況進(jìn)行修改

3. 初始化

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

根據(jù)官方文檔的描述,需要初始化一個(gè)ossClient實(shí)例并將其注入到Spring容器中,因此可以編寫一個(gè)配置類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è)流程:

注:Policy表單域用于驗(yàn)證請(qǐng)求的合法性。例如可以指定上傳的大小,可以指定上傳的Object名稱等,上傳成功后客戶端跳轉(zhuǎn)到的URL,上傳成功后客戶端收到的狀態(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)求,具體流程如下:

用戶只需要在發(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ù)器URL
callback.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:開始。
// callback.addCallbackVar("x:dir", "value");

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

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

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

@Data
public class OssPolicyResult {

	@ApiModelProperty("用戶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

@Data
public class OssCallBackResult {

 @ApiModelProperty("文件的鏈接")
 private String url;
 @ApiModelProperty("文件名稱")
 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)行修改

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

Service 接口:

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

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

@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;

	@Autowired
	private OSS ossClient;

	@Override
	public OssPolicyResult policy() {
		OssPolicyResult result = new OssPolicyResult();
		// 簽名有效期
		long expireEndTime = System.currentTimeMillis() + EXPIRE * 1000;
		Date expiration = new Date(expireEndTime);
		// 文件名稱
		// 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ù)器URL
		callback.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:開始。
		// 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;
	}

	@Override
	public 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")
@RestController
public class OssController {
	
	@Autowired
	private 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)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java二分查找算法實(shí)現(xiàn)代碼實(shí)例

    Java二分查找算法實(shí)現(xiàn)代碼實(shí)例

    這篇文章主要介紹了Java二分查找算法實(shí)現(xiàn)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • JAVA如何獲取30天或某段范圍日期

    JAVA如何獲取30天或某段范圍日期

    JAVA獲取30天或某段范圍日期的方法,在項(xiàng)目使用中比較頻繁,通過(guò)示例代碼介紹了Java獲取當(dāng)前時(shí)間的上一年、下一年、上個(gè)月、下個(gè)月、前一天,當(dāng)天,本周,上周,本季度,上季度等(時(shí)間格式化),感興趣的朋友一起看看吧
    2023-10-10
  • Spring中自定義數(shù)據(jù)類型轉(zhuǎn)換的方法詳解

    Spring中自定義數(shù)據(jù)類型轉(zhuǎn)換的方法詳解

    Spring3引入了一個(gè)core.onvert包,提供一個(gè)通用類型轉(zhuǎn)換系統(tǒng)。在Spring容器中,可以使用這個(gè)系統(tǒng)作為PropertyEditor實(shí)現(xiàn)的替代,將外部化的bean屬性值字符串轉(zhuǎn)換為所需的屬性類型。本文將詳解這一系統(tǒng)的使用方法,需要的可以參考一下
    2022-06-06
  • 使用Spring?Boot?2.x構(gòu)建Web服務(wù)的詳細(xì)代碼

    使用Spring?Boot?2.x構(gòu)建Web服務(wù)的詳細(xì)代碼

    這篇文章主要介紹了使用Spring?Boot?2.x構(gòu)建Web服務(wù)的詳細(xì)代碼,主要基于JWT的身份認(rèn)證,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • springboot整合shardingjdbc實(shí)現(xiàn)分庫(kù)分表最簡(jiǎn)單demo

    springboot整合shardingjdbc實(shí)現(xiàn)分庫(kù)分表最簡(jiǎn)單demo

    我們知道分庫(kù)分表是針對(duì)某些數(shù)據(jù)量持續(xù)大幅增長(zhǎng)的表,比如用戶表、訂單表等,而不是一刀切將全部表都做分片,這篇文章主要介紹了springboot整合shardingjdbc實(shí)現(xiàn)分庫(kù)分表最簡(jiǎn)單demo,需要的朋友可以參考下
    2021-06-06
  • IntellJ idea使用FileWatch實(shí)時(shí)編譯less文件的方法

    IntellJ idea使用FileWatch實(shí)時(shí)編譯less文件的方法

    這篇文章主要介紹了IntellJ idea使用FileWatch實(shí)時(shí)編譯less文件的相關(guān)資料,需要的朋友可以參考下
    2018-02-02
  • Spring實(shí)戰(zhàn)之調(diào)用實(shí)例工廠方法創(chuàng)建Bean操作示例

    Spring實(shí)戰(zhàn)之調(diào)用實(shí)例工廠方法創(chuàng)建Bean操作示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之調(diào)用實(shí)例工廠方法創(chuàng)建Bean操作,結(jié)合實(shí)例形式分析了實(shí)例工廠方法創(chuàng)建Bean相關(guān)配置、實(shí)現(xiàn)方法及操作注意事項(xiàng),需要的朋友可以參考下
    2019-11-11
  • Java實(shí)現(xiàn)指定線程執(zhí)行順序的三種方式示例

    Java實(shí)現(xiàn)指定線程執(zhí)行順序的三種方式示例

    這篇文章主要介紹了Java實(shí)現(xiàn)指定線程執(zhí)行順序的三種方式,包括通過(guò)共享對(duì)象鎖加上可見變量,通過(guò)主線程Join()以及通過(guò)線程執(zhí)行時(shí)Join()等三種實(shí)現(xiàn)方法,需要的朋友可以參考下
    2019-01-01
  • Java中的JPA實(shí)體關(guān)系:JPA一對(duì)一,一對(duì)多(多對(duì)一),多對(duì)多

    Java中的JPA實(shí)體關(guān)系:JPA一對(duì)一,一對(duì)多(多對(duì)一),多對(duì)多

    Java Persistence API(JPA)是Java平臺(tái)上的一個(gè)對(duì)象關(guān)系映射(ORM)規(guī)范,用于簡(jiǎn)化數(shù)據(jù)庫(kù)操作,其中實(shí)體關(guān)系的映射是核心內(nèi)容之一,本文將深入淺出地探討JPA中的三種基本實(shí)體關(guān)系類型:一對(duì)一、一對(duì)多、多對(duì)多,揭示常見問(wèn)題、易錯(cuò)點(diǎn)及其避免策略,希望能幫助大家
    2024-06-06
  • Spring?Boot中的@EnableAutoConfiguration注解詳解

    Spring?Boot中的@EnableAutoConfiguration注解詳解

    這篇文章主要介紹了Spring?Boot中的@EnableAutoConfiguration注解詳解,Spring?Boot是一個(gè)非常流行的Java框架,它可以快速創(chuàng)建基于Spring的應(yīng)用程序。Spring?Boot提供了許多自動(dòng)配置功能,使得開發(fā)者可以非常容易地創(chuàng)建一個(gè)可運(yùn)行的應(yīng)用程序,需要的朋友可以參考下
    2023-08-08

最新評(píng)論