SpringMVC处理文件上传

简要

在SpringMVC中处理文件上传是一件很容易的事。在编写控制器方法处理文件上传之前,我们必须要配置一个multipart解析器,通过它来告诉DispatcherServlet该如何读取multipart请求。

配置multipart解析器

DispatcherServlet没有实现解析multipart请求数据的功能。它将任务委托给Spring中MutipartResolver策略接口实现,通过这个实现类来解析multipart请求中的内容。Spring3.1后内置两个MultipartResolver的实现供我们选择:

  • CommonsMultipartResolver: 使用Jakarta Commons FileUpload解析multipart请求。
  • StandardServletMultipartResolver: 依赖于Servlet3.0对multipart请求的支持。

一般来讲,这两者之间StandardServletMultipartResolver会是优选方案。它使用Servlet所提供的功能支持,并不需要任何其他的项目。如果我们需要将应用部署到Servlet3.0之前的容器中,或者还没有使用Spring3.1或更高版本,那么可能就需要CommonsMultipartResolver了。

使用StandardServletMultipartResolver

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

既然这个@Bean方法如此简单,那我们该如何限制StandardServletMultipartResolver的工作方式呢?
具体来讲,我们必须要在web.xml或Servlet初始化类中,将multipart的具体细节作为DispatcherServlet配置的一部分。
因为我们配置的DispatcherServlet的Servlet初始化类继承了AbstractAnnotationConfigDispatcherServletInitializer,我们需要在初始化类中通过重载customizeRegistration()方法来配置multipart的具体细节。

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { RootConfig.class };      //指定根配置类,例如:application.xml
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { WebConfig.class };        //ָ指定Web配置类,例如:springMVC.xml
    }

    @Override
    protected String[] getServletMappings() {    //将DispatcherServlet映射到"/"
        return new String[] { "/" };
    }

    @Override
    protected void customizeRegistration(Dynamic registration) {  
        registration.setMultipartConfig(               //通过重载customizeRegistration()方法来配置multipart的具体细节
            new MultipartConfigElement("/tmp/uploads",2097152,4194304,0));  
            //设置写入的临时路径
            //上传文件的最大容量(字节为单位),默认无限制。
            //整个multipart请求的最大容量(字节为单位),默认无限制。
            //在上传的过程中,如果文件大小达到了一个指定的最大容量,将会写入到临时文件路劲中。默认为0,也就是上传的文件都会写入到磁盘上。
    }       

}

处理multipart请求

upload.jsp

<form action="/JavaConfigSpringMVC/upload" method="post" enctype="multipart/form-data">
<label>upload picture </label>
<input type="file" name="profilePicture" accept="image/jpeg,image/png" />
<input type="submit" value="提交">
</form>

upload.java

@RequestMapping(value="/upload")  
    public String processRegistration(  
    @RequestPart("profilePicture") byte[] profilePicture // 当表单提交的时候profilePicture属性将会给定一个Byte
                                                         //数组,这个数组中包含了请求中对应part的数据(通过@RequestPart指定)
   ) 
   {  

   }  

上传的图片如下

MultipartFile

使用上传文件的原始byte比较简单但是功能有限。因此,Spring还提供了MultipartFile接口,它为处理multipart提供了内容更为丰富的对象。

public abstract interface MultipartFile {
  String getName();
  String getOriginalFilename();
  String getContentType();
  boolean isEmpty();
  long getSize();
  byte[] getBytes() throws java.io.IOException;
  InputStream getInputStream() throws java.io.IOException;
  void transferTo(File arg0) throws IOException,IllegalStateException;
}

修改processRegistration()方法如下

@RequestMapping(value="/uploads")  
    public String processRegistration(  
    @RequestPart("profilePicture") MultipartFile profilePicture    
   ) throws IllegalStateException, IOException 
   {  
    profilePicture.transferTo(new File(profilePicture.getOriginalFilename()));
    System.out.println(profilePicture.getOriginalFilename());//获得上传文件的名字
    System.out.println(profilePicture.getName());//获取对象的名字
    System.out.println(profilePicture.getContentType());//获取文件的类型
    System.out.println(profilePicture.getSize());//获取文件的大小

    return "hello"; 
   } 

上传的图片

以Part的形式接受上传的文件

如果你需要将应用部署到Servlet3.0的 容器中,那么会有MultipartFile的一个替代方案。SpringMVC也能接受javax.servlet.http.Part作为控制器方法的参数。如果使用Part来替代MultipartFile的话,那么processRegistration()方法如下:

@RequestMapping(value="/uploadByPart")  
    public String processRegistration(  
    @RequestPart("profilePicture") Part profilePicture // Part形式     
   ) throws IllegalStateException, IOException 
   {  
    profilePicture.write(profilePicture.getSubmittedFileName());
    System.out.println(profilePicture.getSubmittedFileName());//获得上传文件的名字,对应于getOriginalFilename()
    System.out.println(profilePicture.getName());             //获取对象的名字
    System.out.println(profilePicture.getContentType());      //获取文件的类型
    System.out.println(profilePicture.getSize());             //获取文件的大小

    return "hello"; 
   } 

Part接口

public abstract interface javax.servlet.http.Part {
  InputStream getInputStream() throws java.io.IOException;  
  String getContentType();  
  String getName();  
  String getSubmittedFileName();  
  long getSize();
  void write(String arg0) throws java.io.IOException;
  void delete() throws java.io.IOException;
  String getHeader(String arg0);
  Collection getHeaders(String arg0);
  Collection getHeaderNames();
}

Part接口与MultipartFile并没有什么太大的区别。

使用CommonsMultipartResolver

如果我们需要将应用部署到Servlet3.0之前的容器中,或者还没有使用Spring3.1或更高版本,那么可能就需要CommonsMultipartResolver了。

@Bean
    public MultipartResolver multipartResolver() throws IOException
    {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        //CommonsMultipartResolver不会强制要求设置临时文件路径。默认情况下,这个路径就是Servlet容器的临时目录,不过可以通过setUploadTempDir属性设置。
        multipartResolver.setUploadTempDir(new FileSystemResource("D:\\uploads"));//需要绝对路径
        //multipartResolver.setUploadTempDir(new FileSystemResource("/tmp/uploads"));
        multipartResolver.setMaxInMemorySize(0);//最大内存大小
        multipartResolver.setMaxUploadSize(2097152);//最大文件容量
        return multipartResolver;

    }

上传图片
该种方式需要commons-io-2.4.jar
以上只是学习Spring实战所写的笔记,如有错误,请指正。谢谢

猜你喜欢

转载自blog.csdn.net/z1790424577/article/details/80723081