Загрузка и загрузка файла Spring Boot
Загрузка и загрузка файлов — одна из наиболее часто используемых функций веб-приложений.В этой главе я буду использовать простой пример, чтобы объяснить, как загружать и скачивать файлы в Spring Boot. Прежде чем начать текст, давайте рассмотрим простой процесс загрузки и скачивания файлов через интеллект-карту:
1. Загрузка файла
Для загрузки файла параметр соответствующего метода загрузки в контроллере должен бытьMultipartFileобъект,MultipartFileОбъект может быть объектом-массивом или отдельным объектом. Если это объект-массив, может быть выполнена загрузка нескольких файлов; здесь мы демонстрируем только загрузку одного файла. Следующий код показывает базовую структуру метода загрузки файла:
@PostMapping(value = "/upload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public String fileUpload(@RequestParam("file") MultipartFile file) throws IOException {
return null;
}
Далее мы используемFileOutputStreamОбъект записывает загруженный клиентом файл на диск и возвращает сообщение "Файл успешно загружен". Ниже приведен полный код для загрузки файла:
package com.ramostear.application.controller;
import com.ramostear.application.model.FileInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author : ramostear
* @date : 2019/3/8 0008-15:35
*/
@Controller
public class FileController {
@Value ( "${file.upload.root.dir}" )
String fileUploadRootDir;
private static Map<String,FileInfo> fileRepository = new HashMap<>();
@PostConstruct
public void initFileRepository(){
FileInfo file1 = new FileInfo ().setFileName ( "bg1.jpg" );
FileInfo file2 = new FileInfo ().setFileName ( "bg2.jpg" );
FileInfo file3 = new FileInfo ().setFileName ( "bg3.jpg" );
fileRepository.put ( file1.getName (),file1 );
fileRepository.put ( file2.getName (),file2 );
fileRepository.put ( file3.getName (),file3 );
}
@PostMapping(value = "/upload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public String fileUpload(@RequestParam("file") MultipartFile file) throws IOException {
File convertFile = new File ( fileUploadRootDir+file.getOriginalFilename ());
FileOutputStream fileOutputStream = new FileOutputStream ( convertFile );
fileOutputStream.write ( file.getBytes () );
fileOutputStream.close ();
FileInfo fileInfo = new FileInfo()
.setFileName ( file.getOriginalFilename());
fileRepository.put ( fileInfo.getName (),fileInfo);
return "File is upload successfully";
}
}
fileRepositoryИндексная информация для хранения загруженных файлов.
2. Загрузка файла
В приложении Spring Boot мы можем использоватьInputStreamResourceобъект для загрузки файла, в методе загрузки файла нам нужно установить соответствующие свойства объекта HttpHeander через Response, такие какContent-Disposition,Cache-Control,PragmaиExpiresи другие свойства. Кроме того, вам также необходимо указать тип ответа Response. Следующий код дает подробную информацию о загрузке файла:
@GetMapping("/download/{fileName}")
@ResponseBody
public ResponseEntity<Object> downloadFile(@PathVariable(name = "fileName") String fileName) throws FileNotFoundException {
File file = new File ( fileUploadRootDir+fileName);
InputStreamResource resource = new InputStreamResource ( new FileInputStream ( file ) );
HttpHeaders headers = new HttpHeaders();
headers.add ( "Content-Disposition",String.format("attachment;filename=\"%s",fileName));
headers.add ( "Cache-Control","no-cache,no-store,must-revalidate" );
headers.add ( "Pragma","no-cache" );
headers.add ( "Expires","0" );
ResponseEntity<Object> responseEntity = ResponseEntity.ok()
.headers ( headers )
.contentLength ( file.length ())
.contentType(MediaType.parseMediaType ( "application/txt" ))
.body(resource);
return responseEntity;
}
3. Список кодов
3.1 Контроллер загрузки и загрузки файлов
Ниже приведен код для полной загрузки и скачивания файла:
package com.ramostear.application.controller;
import com.ramostear.application.model.FileInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.*;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* @author : ramostear
* @date : 2019/3/8 0008-15:35
*/
@Controller
public class FileController {
@Value ( "${file.upload.root.dir}" )
String fileUploadRootDir;
private static Map<String,FileInfo> fileRepository = new HashMap<>();
@PostConstruct
public void initFileRepository(){
FileInfo file1 = new FileInfo ().setFileName ( "bg1.jpg" );
FileInfo file2 = new FileInfo ().setFileName ( "bg2.jpg" );
FileInfo file3 = new FileInfo ().setFileName ( "bg3.jpg" );
fileRepository.put ( file1.getName (),file1 );
fileRepository.put ( file2.getName (),file2 );
fileRepository.put ( file3.getName (),file3 );
}
@GetMapping("/files")
public String files(Model model){
Collection<FileInfo> files = fileRepository.values ();
model.addAttribute ( "data",files );
return "files";
}
@PostMapping(value = "/upload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public String fileUpload(@RequestParam("file") MultipartFile file) throws IOException {
File convertFile = new File ( fileUploadRootDir+file.getOriginalFilename ());
FileOutputStream fileOutputStream = new FileOutputStream ( convertFile );
fileOutputStream.write ( file.getBytes () );
fileOutputStream.close ();
FileInfo fileInfo = new FileInfo()
.setFileName ( file.getOriginalFilename());
fileRepository.put ( fileInfo.getName (),fileInfo);
return "File is upload successfully";
}
@GetMapping("/download/{fileName}")
@ResponseBody
public ResponseEntity<Object> downloadFile(@PathVariable(name = "fileName") String fileName) throws FileNotFoundException {
File file = new File ( fileUploadRootDir+fileName);
InputStreamResource resource = new InputStreamResource ( new FileInputStream ( file ) );
HttpHeaders headers = new HttpHeaders();
headers.add ( "Content-Disposition",String.format("attachment;filename=\"%s",fileName));
headers.add ( "Cache-Control","no-cache,no-store,must-revalidate" );
headers.add ( "Pragma","no-cache" );
headers.add ( "Expires","0" );
ResponseEntity<Object> responseEntity = ResponseEntity.ok()
.headers ( headers )
.contentLength ( file.length ())
.contentType(MediaType.parseMediaType ( "application/txt" ))
.body(resource);
return responseEntity;
}
}
3.2 Модель данных
Создайте модель данных файловой информации в качестве носителя для загрузки файловой информации.Ниже приведен код FileInfo.java:
package com.ramostear.application.model;
import lombok.Data;
import java.util.Date;
/**
* @author : ramostear
* @date : 2019/3/8 0008-15:25
*/
@Data
public class FileInfo {
private String name;
private Date uploadTime = new Date();
public FileInfo setFileName(String name){
this.setName ( name );
return this;
}
}
3.3 Файлы сборки Maven
Ниже приведен список конфигурации файла pom.xml этого демонстрационного приложения:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ramostear</groupId>
<artifactId>file-handling</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>file-handling</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Примечание. В этом случае в качестве шаблона представления используется механизм шаблонов freemarker.
3.4 Файл конфигурации
Файл application.properties в основном устанавливаетfreemarkerи пользовательский атрибут **file.upload.root.dir**:
spring.freemarker.cache=false
spring.freemarker.prefix=
spring.freemarker.suffix=.html
spring.freemarker.enabled=true
spring.freemarker.charset=UTF-8
spring.freemarker.template-loader-path=classpath:/templates/
file.upload.root.dir = C:/work/upload/
file.upload.root.dirПользовательский атрибут задает каталог для загрузки файлов:C:/work/upload/
3.5 Просмотры
В файле просмотра создается форма формы для загрузки файлов, а также создается список загруженных файлов для обеспечения операций загрузки файлов.
Форма загрузки файла:
Список загрузки файлов:
Описание: файл загружается с использованием метода асинхронной загрузки, и форма не отправляется синхронно.
Код асинхронной операции загрузки файла выглядит следующим образом:
$("#upload").on("click",function () {
var fileObj = document.getElementById("file").files[0];
var form = new FormData();
form.append("file",fileObj);
var xhr = new XMLHttpRequest();
xhr.open("post","http://localhost:8080/upload",true);
xhr.onload = function(event){
alert(event.currentTarget.responseText);
window.location.href = window.location.href;
};
xhr.send(form);
});
4. Упакуйте и запустите
Используйте команду Maven для упаковки приложения, следующая команда пакета maven:
mvn clean install
Запустите приведенную выше команду в окне консоли и подождите, пока maven упакует. Если в консоли отображается сообщение «BUILD SUCCESS», вы можете найти соответствующий файл JAR в целевой папке текущего каталога проекта.
Теперь вы можете запустить файл JAR с помощью следующей команды:
java -jar YOUR_JARFILE_NAME
После успешного запуска JAR-файла в окне консоли можно увидеть следующую информацию:
5. Тест
Откройте браузер и введите в адресной строке:http://localhost:8080/files. Ниже скриншот браузера после успешного запроса:
Далее нажмите на любой изdownloadкнопку, чтобы проверить, нормально ли работает функция загрузки файла:
Наконец, мы проверяем, нормально ли работает функция загрузки файлов. Перед тестированием давайте посмотрим на информацию о файле, хранящуюся в каталоге загрузки файлов:
Далее выбираем файл для загрузки и нажимаемuploadкнопка для загрузки файлов:
На этом этапе файл и загрузка выполнены успешно, мы снова смотрим информацию о файле в каталоге загрузки файлов, чтобы убедиться, что файл успешно записан на диск:
6. Аксессуары
Весь исходный код этой главы был загружен в репозиторий кода Github, вы можете посетить следующий адрес, чтобы получить весь исходный код:GitHub.com/Слеза Рамоса/S…
Автор: Тан Чаохун, оригинальный текст:Загружать и скачивать файлы в программе Spring Boot