首页 > Java框架应用 > Spring MVC 入门教程 > Spring MVC 文件上传

Spring MVC 文件上传

1. 前言

实现文件上传有很多方案。如使用原始的 IO 流或者使用第三方上传插件。

Spring MVC 自带有文件上传组件,能很容易地实现文件上传功能。

本节课程将和大家一起讲解 Spring MVC 是如何处理文件上传的。通过本章节内容的学习,你将掌握使用 MultipartResolver 相关组件简单的实现文件上传。

2. MultipartResolver 组件

多数情况下,页面中的数据都是以字符串格式发送给服务器。但有时,用户需要上传自己的个人头像或者上传文件,或者说以二进制的方式进行数据传送。这时就不能使用字符串的方式传递数据了。

Spring MVC 提供有 MultipartResolver 相关组件实现文件上传,不需要特别引入第三方模块。默认情况下, Spring MVC 没有启用文件上传组件,使用前需要做些简单的配置。

2.1 配置文件上传组件

打开项目中的 WebConfig 文件,添加如下代码:

@Bean
public MultipartResolver multipartResolver() {
    return new StandardServletMultipartResolver();
}

MultipartResolver 是一个接口,约定了文件上传的方法。 StandardServletMultipartResolver 是具体的实现类,用来完成文件上传。

对上传的文件信息进一步进行配置,如限制文件大小、文件类型等。打开 WebInitializer 文件,重写 customizeRegistration() 方法:

@Override
protected void customizeRegistration(Dynamic registration) {
     registration.setMultipartConfig(new MultipartConfigElement(null,2000000,400000,0));
}

MultipartConfigElement()方法可以接收 3 个参数:

  • 第一个参数指定保存上传文件的临时目录。如果指定 null,由 Spring MVC 自己提供;最好不要指定;
  • 第二个参数,文件上传的最小大小限制;
  • 第三个参数,文件上传的最大尺寸限制。

图片描述

2.2 实现流程

准备工作完成,现在实现文件上传。

  1. 编写提交表单;

    选择文件:

表单的 enctype 属性有如下几个选择:

  • application/x-www-form-urlencoded : 在发送前编码所有字符,数据以字符串的方式发送;
  • multipart/form-data: 不对字符编码,使用包含文件上传控件的表单时,必须使用该值;
  • text/plain: 空格转换为 “+” 加号,但不对特殊字符编码。

Tips: 因为表单中包含有文件上传控件,所以,一定要设置表单的 enctype 值为 multipart/form-data

  1. 获取项目上下文绝对路径;

编写控制器之前,先打开 web.xml ,注册一个 org.springframework.web.util.WebAppRootListener 监听器,通过此监听器获取到 Spring MVC 项目的发布的绝对路径,用来为上传的文件指定存储位置。

<context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>webapp.root</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.util.WebAppRootListener</listener-class>
</listener>

Tips: webapp.root 相当于一个变量,可以是符合规范的任意命称。当程序启动时,此监听器会把服务器绝对路径保存在此变量中。使用监听器的方式获取路径可以有效地减少开发者的编码量。

当然,完全可以不使用此监听器,开发者可以在控制器中通过注入原生 Servlet API 编码获取。

  1. 编写控制器:

    @Controller public class UpLoadAction { @RequestMapping("/upload") public String upload(@RequestPart("upFile") byte[] file) throws IOException { String path = System.getProperty("webapp.root"); String filePath = path + "\upload\temp.png"; FileOutputStream fileOutputStream = new FileOutputStream(filePath); FileCopyUtils.copy(file, fileOutputStream); return "success"; } }

解释上面的代码:

  • System.getProperty(“webapp.root”) 可以得到监听器组件得到的项目上下文路径。在项目的根目录下新建 upload 目录,用来存储上传过来的文件;
  • @RequestPart(“upFile”) 注解能注入表单提交上来的文件数据,此数据以 byte[] 类型保存。

使用 @RequestPart(“upFile”) 注解的方式存在些问题,不能获取上传文件的文件名等其它元数据信息。

  1. 实例测试。

打开浏览器,显示上传页面。

图片描述
在本地首先选择好需要上传的文件,然后点击上传。找到 tomcat 中的项目发布目录,可以找到刚上传的文件。
图片描述

2.3 MultipartFile 接口

以字节数组的方式接收上传的文件数据,过于原始、低级,很难获取到文件的元数据。 Spring MVC 提供有 MultipartFile 接口。

查看 MultipartFile 接口源代码,可以知道 MultipartFile 接口提供了很多方法,能解析出上传文件的更多元数据,包括文件名、文件大小等,方便开发者更灵活地处理数据。

public interface MultipartFile extends InputStreamSource {
   String getName();
   @Nullable
   String getOriginalFilename();
   @Nullable
   String getContentType();
   boolean isEmpty();
   long getSize();
   byte[] getBytes() throws IOException;
   @Override
   InputStream getInputStream() throws IOException;
   default Resource getResource() {
    return new MultipartFileResource(this);
   }
   void transferTo(File dest) throws IOException, IllegalStateException;
    default void transferTo(Path dest) throws IOException, IllegalStateException {
        FileCopyUtils.copy(getInputStream(), Files.newOutputStream(dest));
    }
}

MultipartFile 最常用的是 transferTo 方法,用来把上传文件存储到指定位置。

重构上面的控制器代码。

   @RequestMapping("/upload")
   public String upload(@RequestPart("upFile") MultipartFile file) throws IOException {
    String path = System.getProperty("webapp.root");
    String filePath = path + "\\upload\\"+file.getOriginalFilename();
    System.out.println(filePath);
       file.transferTo(new File(filePath));
    return "success";
   }

如上面一样测试文件上传,结果没有什么不一样。

3. 小结

本节和大家讲解了如何使用 Spring MVC 提供的 MultipartResolver 组件完成文件的上传。其配置过程并不很难,但大家需要注意的是,在接收文件数据时会涉及到 @RequestPart 注解、MultipartFile 接口,结合两者能很好的注放上传数据,方便开发者的后续处理。

本文来自互联网用户投稿,不拥有所有权,该文观点仅代表作者本人,不代表本站立场。
访问者可将本网站提供的内容或服务用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯本网站及相关权利人的合法权利。
本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站,邮箱:80764001@qq.com,予以删除。
© 2023 PV138 · 站点地图 · 免责声明 · 联系我们 · 问题反馈