Spring Boot 上传文件

来源:这里教程网 时间:2026-02-17 21:35:59 作者:

Spring Boot 上传文件教程展示了如何使用 Spring Boot 框架上传单个文件。

Spring 是流行的 Java 应用框架,而 Spring Boot 是 Spring 的演进,可以帮助轻松地创建独立的,生产级的基于 Spring 的应用。

HTML 表单的编码类型

POST 请求有三种编码 HTML 表单类型:

应用/ x-www-form-urlencoded多部分/表单数据文字/纯文字

application/x-www-form-urlencoded是默认编码,其中值编码在由&分隔的键值元组中。 =字符用于键和值之间。 非字母数字字符采用百分比编码。 此编码类型不适用于二进制文件。

multipart/form-data用于非 acsii 数据和二进制文件。 input元素的type属性设置为file。

text/plain用于调试。

Spring 上传文件示例

在下面的示例中,我们有一个 Web 表单来选择要上传到服务器的文件。 该文件被上传到/var/www/upload目录。

上传目录

/var/www目录是 Debian Linux 中 Web 内容的标准目录。

$ ls -ld /var/www/upload/drwxrwxr-x 2 www-data www-data 4096 Dec  3 14:29 /var/www/upload/

我们将文件上传到/var/www/upload目录。 www-data组中的用户可以修改目录文件。 因此,运行 Web 服务器的用户必须在此组中。

应用

以下是 Spring Boot Web 应用的来源。

pom.xmlsrc├───main│   ├───java│   │   └───com│   │       └───zetcode│   │           │   Application.java│   │           ├───controller│   │           │       MyController.java│   │           ├───exception│   │           │       StorageException.java│   │           └───service│   │                   StorageService.java│   └───resources│       │   application.properties│       └───static│               failure.html│               index.html│               success.html└───test    └───java

这是 Spring 应用的项目结构。

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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.zetcode</groupId>    <artifactId>springbootuploadfile</artifactId>    <version>1.0-SNAPSHOT</version>    <packaging>jar</packaging>    <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <maven.compiler.source>11</maven.compiler.source>        <maven.compiler.target>11</maven.compiler.target>    </properties>    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.9.RELEASE</version>    </parent>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build></project>

这是 Maven pom.xml文件。

com/zetcode/controller/MyController.java

package com.zetcode.controller;import com.zetcode.exception.StorageException;import com.zetcode.service.StorageService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.multipart.MultipartFile;@Controllerpublic class MyController {    @Autowired    private StorageService storageService;    @RequestMapping(value = "/doUpload", method = RequestMethod.POST,            consumes = {"multipart/form-data"})    public String upload(@RequestParam MultipartFile file) {        storageService.uploadFile(file);        return "redirect:/success.html";    }    @ExceptionHandler(StorageException.class)    public String handleStorageFileNotFound(StorageException e) {        return "redirect:/failure.html";    }}

MyController从请求中读取文件并将其保存到所选目录中。

@Autowiredprivate StorageService storageService;

StoreageService将文件存储在磁盘上。

@RequestMapping(value = "/doUpload", method = RequestMethod.POST,    consumes = {"multipart/form-data"})public String upload(@RequestParam MultipartFile file) {

upload()方法映射到doUpload URL 模式。 由于我们正在将数据发送到服务器,因此我们使用 POST 请求。 请求参数具有MultipartFile类型。

return "redirect:/success.html";

成功上传文件后,我们会显示一条消息。

@ExceptionHandler(StorageException.class)public String handleStorageFileNotFound(StorageException e) {    return "redirect:/failure.html";}

我们有StorageException的处理程序。

com/zetcode/StorageException.java

package com.zetcode.exception;public class StorageException extends RuntimeException {    public StorageException(String message) {        super(message);    }    public StorageException(String message, Throwable cause) {        super(message, cause);    }}

这是我们的自定义StorageException。 当文件无法存储在文件系统上时,将引发该错误。

com/zetcode/service/StorageService.java

package com.zetcode.service;import com.zetcode.exception.StorageException;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import org.springframework.web.multipart.MultipartFile;import java.io.IOException;import java.nio.file.Files;import java.nio.file.Paths;import java.nio.file.StandardCopyOption;@Servicepublic class StorageService {    @Value("${upload.path}")    private String path;    public void uploadFile(MultipartFile file) {        if (file.isEmpty()) {            throw new StorageException("Failed to store empty file");        }        try {            var fileName = file.getOriginalFilename();            var is = file.getInputStream();            Files.copy(is, Paths.get(path + fileName),                    StandardCopyOption.REPLACE_EXISTING);        } catch (IOException e) {            var msg = String.format("Failed to store file", file.getName());            throw new StorageException(msg, e);        }    }}

StorageService从输入流复制数据并将其保存在磁盘上。

@Value("${upload.path}")private String path;

我们使用@Value注解从application.properties文件中读取上传目录。

if (file.isEmpty()) {    throw new StorageException("Failed to store empty file");}

我们确保已使用isEmpty()方法选择了一个文件。

var fileName = file.getOriginalFilename();

我们使用getOriginalFilename()方法获得文件名。

var is = file.getInputStream();

我们使用getInputStream()方法获得输入流。

Files.copy(is, Paths.get(path + fileName),        StandardCopyOption.REPLACE_EXISTING);

该文件被复制到从与Files.copy()输入流源的目标目录。

resources/application.properties

upload.path=/var/www/upload/

在application.properties中,我们有一个upload.path属性,用于指定上传目录。

resources/static/index.html

<!DOCTYPE html><html>    <head>        <title>Uploading file</title>        <meta charset="UTF-8">        <meta name="viewport" content="width=device-width, initial-scale=1.0">    </head>    <body>        <h1>Uploading file</h1>        <form action="/doUpload" method="post" enctype="multipart/form-data">            <label>Enter file</label>            <input type="file" name="file">            <button type="submit">Upload</button>        </form>    </body></html>

这是主页。 它是src/main/resources/static目录中的静态文件。 它包含一个用于选择文件并将其发送到 Spring 应用的表单。

<form action="/doUpload" method="post" enctype="multipart/form-data">

我们选择了doUpload URL 模式。 此表单创建的请求将由 Spring 控制器处理。 enctype属性指定multipart/form-data编码类型,这是使用 HTML 格式上传文件所必需的。

<input type="file" name="file">

input标签的type属性使用户可以选择文件。

<button type="submit">Upload</button>

最后,这是一个提交按钮。

resources/static/success.html

<!DOCTYPE html><html>    <head>        <title>Success</title>        <meta charset="UTF-8">        <meta name="viewport" content="width=device-width, initial-scale=1.0">    </head>    <body>        <p>File successfully uploaded</p>    </body></html>

文件成功上传到服务器后,将显示success.html。

resources/static/failure.html

<!DOCTYPE html><html>    <head>        <title>Failure</title>        <meta charset="UTF-8">        <meta name="viewport" content="width=device-width, initial-scale=1.0">    </head>    <body>        <p>Failed to upload file</p>    </body></html>

文件上传失败时,将显示failure.html。

Application.java

package com.zetcode;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class Application  {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

这段代码设置了 Spring Boot 应用。

在本教程中,我们学习了如何在 Spring 应用中上传文件。

相关推荐