MultipartFile & MultipartResolver & CommonsMultipartResolver & MultipartHttpServletRequest

一、MultipartFile

在Java中处理文件向来是一种不是很方便的操作,然后随着Spring框架的崛起,使用Spring框架中的MultipartFile来处理文件是件很方便的事了,

(一)概述

 MultipartFile为org.springframework.web.mutipart包下的一个类,也就是说如果想使用MultipartFile这个类就必须引入spring框架,换句话说,如果想在项目中使用MultipartFile这个类,那么项目必须要使用spring框架才可以,否则无法引入这个类。

MultipartFile翻译成中文来讲就是“多组件的文档”,不用太在乎他的中文含义,一般来讲使用MultipartFile这个类主要是来实现以表单的形式进行文件上传功能。

(二)理解什么是MultipartFile

1、MultipartFile类的注释说明

MultipartFile类的注释说明翻译,我们知道:

第一句:一种可以接收使用多种请求方式来进行上传文件的代表形式。也就是说,如果你想用spring框架来实现项目中的文件上传功能,则MultipartFile可能是最合适的选择,而这里提到的多种请求方式则可以通俗理解为以表单的形式提交。

第二句:这个文件内容可以存储到内存中或者存储在磁盘的临时位置上。

第三句:无论发生哪种情况,用户都可以自由地拷贝文件内容到session存储中,或者以一种永久存储的形式进行存储,如果有需要的话。

第四句:这种临时性的存储在请求结束之后将会被清除掉。

2、MultipartFile常用方法解析

首先MultipartFile是一个接口,并继承自InputStreamSource,且在InputStreamSource接口中封装了getInputStream方法,该方法的返回类型为InputStream类型,这也就是为什么MultipartFile文件可以转换为输入流。通过以下代码即可将MultipartFile格式的文件转换为输入流。

multipartFile.getInputStream();

  (1)、getName方法

getName方法获取的是前后端约定的传入文件的参数的名称,在SpringBoot后台中则是通过@Param("uploadFile") 注解定义的内容。

getName方法返回的name值从来不是null或者空,也就是说如果使用MultipartFile来接收文件,那么@Param("uploadFile")定义的接收文件的名称则必不可少,这样才能接收到文件,如果没有定义@Param("uploadFile"),则接收不到文件。

 (2)、getOriginalFileName方法 

getOriginalFileName方法获取的是文件的完整名称,包括文件名称+文件拓展名。

 (3)、getContentType方法 

getContentType方法获取的是文件的类型,注意是文件的类型,不是文件的拓展名。

 (4)、isEmpty方法 

isEmpty方法用来判断传入的文件是否为空,如果为空则表示没有传入任何文件。

 (5)、getSize方法 

getSize方法用来获取文件的大小,单位是字节。

 (6)、getBytes方法 

getBytes方法用来将文件转换成一种字节数组的方式进行传输,会抛出IOException异常。

 (7)、getInputStream方法 

getInputStream方法用来将文件转换成输入流的形式来传输文件,会抛出IOException异常。

 (8)、transferTo方法 

transferTo方法用来将接收文件传输到给定目标路径,会抛出IOException、IllegalStateException异常。该方法在实际项目开发中使用较少。

(三)MultipartFile的一些使用技巧

(1)我们在使用MultipartFile作为参数传递的时候,可以将MultipartFile声明为一个数组,这样就能支持多文件传输,如果只需要传输一个文件,则去掉数组就好了。

(2)可以根据MultipartFile的getSize方法来获取到传输文件的大小,这样就能限定传输过来的文件的大小了。

二、MultipartResolver

MultipartResolver是用于处理文件上传,当收到请求时DispatchServlet的checkMultipart()方法会调用MultipartResolver的isMultipart()方法判断请求中是否包含文件。

如果请求数据中包含文件,则调用MultipartResolver的resolverMultipart()方法对请求的数据进行解析,然后将文件数据解析成MultipartFile并封装在MultipartHTTPServletRequest(继承了HTTPServletRequest)对象中,最后传递给Controller

在MultipartResolver接口中有如下方法:

//判断是否存在文件流
boolean isMultipart(HttpServletRequest request);
//解析http请求,并将请求封装到MultipartHttpServletRequest对象中,
MultipartHttpServletRequest resolveMultipart(HttpservletRequest request);
//清理上传的资源
void cleanMultipart(HttpServletRequest request);

CommonsMultipartResolverStandardServletMultipartResolver 是其实现类

二者的区别:

  1. 第一个需要使用 Apache 的 commons-fileupload 等 jar 包支持,但它能在比较旧的 servlet 版本中使用。
  2. 第二个不需要第三方 jar 包支持,它使用 servlet 内置的上传功能,但是只能在 Servlet 3 以上的版本使用。

三、CommonsMultipartResolver

(一)概述

public class CommonsMultipartResolver extends CommonsFileUploadSupport 
                              implements MultipartResolver, ServletContextAware {
……
……
}

 

CommonsMultipartResolver是MultipartResolver接口的实现类

(二)方法

//清理所有资源
void cleanupMultipart(MultipartHttpServletRequest request);
//决定给定请求的编码 protected String determineEncoding(HttpServletRequest request);
//判断是否存在文件流
boolean isMultipart(HttpservletRequest request);
//解析给定的servlet请求,解析其多部分元素 protected CommonsFileUploadSupport.MultipartParsingResult parseRequest(HttpServletRequest request)
//将给定http请求解析为多部分文件和参数 MultipartHttpServletRequest resolveMultipart(HttpServletRequest request)
//设置是否在文件或参数访问时延迟解决多部分请求。 void setResolveLazily(boolean resolveLazily)
//设置ServletContext运行该对象的位置。 void setServletContext(ServletContext servletContext)

四、MultipartHttpServletRequest

用户必须能够上传图片,因此需要文件上传的功能。比较常见的文件上传组件有Commons FileUpload(http://jakarta.apache.org/commons/fileupload/a>)和COS FileUpload(http://www.servlets.com/cos),Spring已经完全集成了这两种组件,这里我们选择Commons FileUpload。

由于Post一个包含文件上传的Form会以multipart/form-data请求发送给服务器,必须明确告诉DispatcherServlet如何处理MultipartRequest。首先在dispatcher-servlet.xml中声明一个MultipartResolver:

xml 代码

<bean id="multipartResolver"  
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
    <!-- 设置上传文件的最大尺寸为1MB -->  
    <property name="maxUploadSize">  
        <value>1048576</value>  
    </property>  
</bean>  

这样一旦某个Request是一个MultipartRequest,它就会首先被MultipartResolver处理,然后再转发相应的Controller

在UploadImageController中,将HttpServletRequest转型为MultipartHttpServletRequest,就能非常方便地得到文件名和文件内容:

public ModelAndView handleRequest(HttpServletRequest request,   
            HttpServletResponse response) throws Exception {   
        // 转型为MultipartHttpRequest:   
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;   
        // 获得文件:   
        MultipartFile file = multipartRequest.getFile(" file ");   
        // 获得文件名:   
        String filename = file.getOriginalFilename();   
        // 获得输入流:   
        InputStream input = file.getInputStream();   
        // 写入文件   
  
        // 或者:   
        File source = new File(localfileName.toString());   
        multipartFile.transferTo(source);   
    }  

 

posted @ 2023-05-31 13:09  ImreW  阅读(838)  评论(0编辑  收藏  举报