找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,訪問微社區

只需一步,快速開始

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

查看: 1848| 評論: 1| 發布者: isxichen

??? ??С
簡介:Spring Boot 2.0 Restful Style MultipartFile Upload and Download APIs文件上傳與下載在Web應用中是一個比較常見的功能。在本教程中,我將基于Spring 2.2.6版本實現一個基于Restful風格的文件上傳與下載APIs; ...

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

Spring Boot 2.0 Restful Style MultipartFile Upload and Download APIs


文件上傳與下載在Web應用中是一個比較常見的功能。在本教程中,我將基于Spring 2.2.6版本實現一個基于Restful風格的文件上傳與下載APIs。

基于Spring Boot 2.0實戰系列源碼已經Push到Github倉庫:https://github.com/ramostear/springboot2.0-action 。感興趣的朋友歡迎Star/Fork。

1. 環境

  • JDK: Java 1.8
  • Framework: Spring Boot 2.2.6(Only Using Spring Web MVC)
  • Maven: Maven 3.5.0+
  • IDE: IntelliJ IDEA 2019.2
  • Test: Postman 7.23.0

2. 功能


本教程中,使用Spring 2.2.6實現Restful風格的APIs并提供以下的功能:
  • 1.客戶端上傳文件到服務端
  • 2.對客戶端上傳文件大小進行限制(50MB)
  • 3.點擊鏈接地址下載文件
  • 4.獲得已上傳文件列表(文件名和下載地址)

下面是教程所實現的APIs列表(服務端請求端口默認8080):

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

APIs


3.工程結構

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

Project Architecture


工程目錄結構說明如下:
  • 1.config/FileUploadConfiguration.java: 常規組件,主要在重啟應用時清理歷史文件;
  • 2.controller/FileUploadController.java: 主要的控制器,負責處理文件的上傳,下載,瀏覽等請求;
  • 3.exception/FileUploadExceptionAdvice.java: 全局的異常處理類,提供用戶友好的異常提示信息;
  • 4.service/FileStorageService.java: 文件上傳接口類,提供存儲地址初始化,保存文件,加載文件,清理文件等操作;
  • 5.service/impl/FileStorageServiceImpl.java: 文件上傳接口實現類;
  • 6.valueobject/UploadFile.java: 封裝了文件名和存儲地址的POJO類;
  • 7.valueobject/Message.java: 請求/響應的消息對象;
  • 8.resources/application.yml: 項目配置文件,主要配置了文件上傳大小限制;
  • 9.pom.xml:Maven依賴配置文件。

4 創建Spring Boot項目


本教程是基于IntelliJ IDEA創建Spring Boot項目的,你也可以選擇自己喜歡的IDE創建項目。創建完項目后,請檢查pom.xml文件中是否包含如下配置:

org.springframework.boot
spring-boot-starter-web


本教程只使用到Spring Web MVC的功能,因此只需添加spring-boot-starter-web依賴。

4.1 文件上傳接口


按照面向接口編程的約定(規范),創建一個用于操作上傳文件的接口類FileStorageService.java,并提供相應的方法。

service/FileStorageService.java
package com.ramostear.springboot.uploadfile.service;

import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Path;
import java.util.stream.Stream;

/**
* @ClassName FileStorageService
* @Description TODO
* @Author 樹下魅狐
* @Date 2020/4/28 0028 18:35
* @Version since 1.0
**/
public interface FileStorageService {

void init();

void save(MultipartFile multipartFile);

Resource load(String filename);

Stream load();

void clear();

}

在啟動應用時,先調用clear()方法清理歷史文件,再調用init()方法初始化文件上傳地址。

4.2 實現文件上傳接口


文件上傳接口實現類比較簡單,這里直接給出代碼:

service/impl/FileStorageServiceImpl.java
/**
* @ClassName FileStorageServiceImpl
* @Description TODO
* @Author 樹下魅狐
* @Date 2020/4/28 0028 18:38
* @Version since 1.0
**/
@Service("fileStorageService")
public class FileStorageServiceImpl implements FileStorageService {

private final Path path = Paths.get("fileStorage");

@Override
public void init() {
try {
Files.createDirectory(path);
} catch (IOException e) {
throw new RuntimeException("Could not initialize folder for upload!");
}
}

@Override
public void save(MultipartFile multipartFile) {
try {
Files.copy(multipartFile.getInputStream(),this.path.resolve(multipartFile.getOriginalFilename()));
} catch (IOException e) {
throw new RuntimeException("Could not store the file. Error:"+e.getMessage());
}
}

@Override
public Resource load(String filename) {
Path file = path.resolve(filename);
try {
Resource resource = new UrlResource(file.toUri());
if(resource.exists() || resource.isReadable()){
return resource;
}else{
throw new RuntimeException("Could not read the file.");
}
} catch (MalformedURLException e) {
throw new RuntimeException("Error:"+e.getMessage());
}
}

@Override
public Stream load() {
try {
return Files.walk(this.path,1)
.filter(path -> !path.equals(this.path))
.map(this.path::relativize);
} catch (IOException e) {
throw new RuntimeException("Could not load the files.");
}
}

@Override
public void clear() {
FileSystemUtils.deleteRecursively(path.toFile());
}
}

其中,Files、Path和Paths是java.nio.file提供的類,Resource是org.springframework.core.io包中提供的類。

4.3 定義值對象


本教程中,定義了兩個簡單的對象UploadFile.java和Message.java,分別封裝了上傳文件信息和響應消息,代碼如下:

valueobject/UploadFile.java
/**
* @ClassName UploadFile
* @Description TODO
* @Author 樹下魅狐
* @Date 2020/4/28 0028 18:48
* @Version since 1.0
**/
public class UploadFile {

private String fileName;
private String url;

public UploadFile(String fileName, String url) {
this.fileName = fileName;
this.url = url;
}

public String getFileName() {
return fileName;
}

public void setFileName(String fileName) {
this.fileName = fileName;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}

valueobject/Message.java
/**
* @ClassName Message
* @Description TODO
* @Author 樹下魅狐
* @Date 2020/4/28 0028 19:21
* @Version since 1.0
**/
public class Message {

private String message;

public Message(String message) {
this.message = message;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}

4.4 控制器


在controller包下創建文件上傳控制器,用于處理客戶端的請求。代碼如下:

controller/FileUploadController.java
/**
* @ClassName FileUploadController
* @Description TODO
* @Author 樹下魅狐
* @Date 2020/4/28 0028 18:52
* @Version since 1.0
**/
@RestController
public class FileUploadController {

@Autowired
FileStorageService fileStorageService;

@PostMapping("/upload")
public ResponseEntity upload(@RequestParam("file")MultipartFile file){
try {
fileStorageService.save(file);
return ResponseEntity.ok(new Message("Upload file successfully: "+file.getOriginalFilename()));
}catch (Exception e){
return ResponseEntity.badRequest()
.body(new Message("Could not upload the file:"+file.getOriginalFilename()));
}
}

@GetMapping("/files")
public ResponseEntity> files(){
List files = fileStorageService.load()
.map(path -> {
String fileName = path.getFileName().toString();
String url = MvcUriComponentsBuilder
.fromMethodName(FileUploadController.class,
"getFile",
path.getFileName().toString()
).build().toString();
return new UploadFile(fileName,url);
}).collect(Collectors.toList());
return ResponseEntity.ok(files);
}

@GetMapping("/files/{filename:.+}")
public ResponseEntity getFile(@PathVariable("filename")String filename){
Resource file = fileStorageService.load(filename);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment;filename=\\""+file.getFilename()+"\\"")
.body(file);
}
}

在控制器中,使用@RestController組合注解替換了@[email protected]的注解方式,并采用@RequestMapping的快捷方式注解方法。

4.5配置上傳文件大小


通常,出于安全和性能考慮,我們需要限定客戶端上傳文件的大小,本教程限定的文件大小最大為50MB。在application.yml(application.properties)文件中添加如下配置:

application.yml
spring:
servlet:
multipart:
max-request-size: 50MB
max-file-size: 50MB

application.properties
spring.servlet.multipart.max-request-size=50MB
spring.servlet.multipart.max-file-size=50MB

spring.servlet.multipart.max-request-size=50MB: 單次請求所能上傳文件的總文件大小spring.servlet.multipart.max-file-size=50MB:單個文件所能上傳的文件大小

4.6 全局異常處理


在控制器中,文件上傳過程中可能產生的異常我們使用try-catch語句進行了用戶友好處理,但當客戶端上傳文件大小超過50MB時,應用會拋出MaxUploadSizeExceededException異常信息,我們需要對此異常信息做處理。最簡單的方式是使用@[email protected]組合方式處理異常。在exception包下創建異常處理類,代碼如下:

exception/FileUploadExceptionAdvice.java
/**
* @ClassName FileUploadExceptionAdvice
* @Description TODO
* @Author 樹下魅狐
* @Date 2020/4/28 0028 19:10
* @Version since 1.0
**/
@ControllerAdvice
public class FileUploadExceptionAdvice extends ResponseEntityExceptionHandler {

@ExceptionHandler(MaxUploadSizeExceededException.class)
public ResponseEntity handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e){
return ResponseEntity.badRequest().body(new Message("Upload file too large."));
}
}

4.7 初始化文件存儲空間


為了在測試時獲得干凈的測試數據,同時也為了在應用啟動后分配好上傳文件存儲地址,我們需要在config包下創建一個配置類,在應用啟動時調用FileStorageService中的clear()方法和init()方法。實現該功能,最快的方式是配置類實現CommandLineRunner接口類的run()方法,代碼如下:

config/FileUploadConfiguration.java
@Service
public class FileUploadConfiguration implements CommandLineRunner {

@Autowired
FileStorageService fileStorageService;

@Override
public void run(String... args) throws Exception {
fileStorageService.clear();
fileStorageService.init();
}
}

使用@Autowired注解將FileStorageService注入到FileUploadConfiguration.java中。

5.運行程序并測試


運行Spring Boot應用程序的方式有很多,例如:
  • 1.命令方式:mvn spring-boot:run
  • 2.IntelliJ IDEA:點擊IntelliJ IDEA的“Run”按鈕
  • 3.main()方法:直接運行主類中的main()方法
  • 4.運行jar包:java -jar springboot-fileupload.jar

選擇一種你比較熟悉的方式運行Spring Boot應用程序。當應用程序啟動成功后,該項目的根目錄會創建一個名為fileStorage的文件夾,該文件夾將用于存放客戶端上傳的文件。

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

Files Storage Folder

5.1 使用Postman對APIs進行測試


應用程序啟動成功后,我們使用Postman對應用程序中的APIs進行測試。

$調用/upload接口上傳文件:

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

Test upload file api

$上傳一個大小超過50MB的文件

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

test large file


執行結果:

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

test result

$檢查文件存儲文件夾


文件上傳成功后,我們可以查看項目根目錄下的fileStorage文件夾,檢查是否有文件被存儲到當中:

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

check file storage folder

$調用/files接口,獲取所有已上傳文件列表

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

test file list api


/files接口將返回所有已上傳的文件信息,我們可以點擊其中任意一個鏈接地址下載文件。在Postman中,可以通過header選項卡查看響應頭中文件的詳細信息,例如:

Spring Boot 2.0實現Rest風格的文件上傳與下載APIs(附源碼)

download file


你也可以復制列表中的鏈接地址,并在瀏覽器中訪問該地址,瀏覽器會彈出一個下載詢問對話框,點擊確定按鈕進行下載。

6 總結


本章節介紹了Spring Boot 2.0實現基于Restful風格的文件上傳和下載APIs,并使用Postman工具對APIs進行測試,達到了設計的預期結果。你可以通過下面的鏈接地址獲取本次教程的相關源代碼。

Github倉庫地址

https://github.com/ramostear/springboot2.0-action

如果你在運行本次教程提供的源代碼過程中遇到什么問題,請在評論區與我聯系。


未經允許,請勿轉載!


【免責聲明】本文僅代表作者或發布者個人觀點,不代表SEO研究協會網(www.989849.buzz)及其所屬公司官方發聲,對文章觀點有疑義請先聯系作者或發布者本人修改,若內容涉及侵權或違法信息,請先聯系發布者或作者刪除,若需我們協助請聯系平臺管理員,郵箱[email protected](本平臺不支持其他投訴反饋渠道,謝謝合作)。若需要學習以上相關知識請到巨推學院觀看視頻教程,網址www.jutuiedu.com。

雞蛋

鮮花

握手

雷人

路過
已有 1 人參與

會員評論

推薦閱讀

    2020-05-27 01:11
  • 作者:cherise

    案例教學:業務人員的AI建模修煉大法

    有人說,不想當將軍的士兵不是好士兵!業務人員也要有點夢想,萬一實現了呢?比如成為“業務數據分析師”!上周,小T介紹了Tempo AI的自動學習功能,這個功能幫助大家解決了機器學習算法這個老大難。但在日常工作中

  • 2020-05-27 01:05
  • 作者:球球

    株洲網絡推廣外包想要“網紅”的流量,缺少長期的積累可是不行的

    托網絡的福,現在咱們每天都能看到許多熱門音訊。刨去那些真實的時事新聞不說,如今可以敏捷走紅的要么是和明星有關的,要么便是一些在平?磥砗軣o聊的工作。但不管怎么說,已然成為了熱門,那么比方會帶來許多的流

  • 2020-05-27 01:02
  • 作者:caryma

    TikTok挖角前微軟知識產權律師任全球總法律顧問

    炣燃科技1月26日訊(江丞華) 1月25日,據外媒報道,字節跳動旗下的海外版抖音TikTok表示,該公司已任命前微軟知識產權律師安德森為全球總法律顧問。據報道,安德森將向TikTok總裁朱駿匯報工作,原職務為微軟首席知

  • 2020-05-27 00:58
  • 作者:yiyuwowo

    商務部相關負責人談2020年1-4月我國服務外包與消費市場總體情況

    服貿司負責人談2020年1-4月我國服務外包產業發展情況2020年1-4月,我國企業承接服務外包合同額3743.9億元人民幣(幣種下同),同比下降6%,執行額2476.5億元,同比增長10.6%。其中,承接離岸服務外包合同額2309.7億

  • 2020-05-27 00:51
  • 作者:烈鷹

    IT外包服務告訴你,企業IT所面臨的問題

    傳統的網絡安全設備,如防火墻、入侵檢測系統、防病毒軟件、反垃圾郵件系統等,構成企業網絡的邊界防護屏障,能夠有效地防護來自互聯網的攻擊,然而它們對于內部員工上網行為不當引起的安全與管理隱患卻無能為力:1

  • 2020-05-27 00:49
  • 作者:苔筑

    Java之父高斯林給年輕程序員們5條建議和價值12880元的Java教程

    今天,我就跟你聊一聊 Java 的創造者,Java 之父 James Gosling。以前寫過這個話題,半途而廢了,今天寫完。作為很早使用 Java 的那一代老程序員,我們都把他老人家親切的稱為高司令,為了方便,下面我會稱呼他為高

  • 2020-05-27 00:48
  • 作者:caryma

    高校成為疫情輿情治理有效“第三方”

    抗擊新冠肺炎疫情是一場沒有硝煙的戰爭。從戰“疫”之初,疫情輿情可謂主戰場之外一個“看不見的戰場”,牽動著國人乃至全世界的脆弱的神經。疫情發生以來,輿論數量和密度均呈爆炸式增長態勢。做好輿情治理和輿情引

  • 2020-05-27 00:41
  • 作者:張之強

    華為手機雖好,但是最值得買的還是這三款

    我們都知道,華為有很多的系列型號,包含榮耀系列、Mate系列、P系列、nave系列以及暢享系列,總共包含多款機器,而購機小白只會看上外觀,絲毫不懂配置而亂買的話,不僅后期會比較卡頓,甚至各方面都表現不佳。不過

  • 2020-05-27 00:40
  • 作者:lantom

    2019投資者理財習慣大調查,最關注產品風險與收益,對理財顧問投

    隨著資本市場的蓬勃發展,金融機構職能范圍和業務領域不斷拓展,理財產品不斷創新,投資者理財習慣也在發生改變。為全面、客觀地了解我國投資者的理財習慣,精準地提供符合投資者需求的理財服務,廣發證券資產管理(

  • 2020-05-27 00:32
  • 作者:溫柔在秋天

    服務器是啥?看這篇就夠了

    一. 什么是服務器 服務器英文名稱為“Server”,指的是網絡環境下為客戶機(Client)提供某種服務的專用計算機,服務器安裝有網絡操作系統(如Windows 2019 Server、Linux、Unix等)和各種服務器應用系統軟件(如Web服務

文章排行

TOP ARTICLES

返回頂部
gpk钱龙捕鱼挂 白小姐四肖必选期期中 福建快3综合走势图 福建快三电视app 2016股票配资平台排名 安徽快3开奖结果今天3徽快3基 搞活动的时时彩平台 12选5开奖浙江定牛 重庆幸运农场快乐可靠吗 青海11选5电子走势图 南京期货配资晓晓