Spring_SpringMVC处理文件上传

世上最快乐的事,莫过于为理想而奋斗。—— 苏格拉底

1、multipart请求

一般表单提交所形成的请求结果时很简单的,就是以"&"符分割的多个name-value对,如:"firstName=Charles&lastName=Bob"。对于典型的基于文本的表单提交,这种编码形式也足够满足要求,但是对于multipart请求中传送二进制数据,就显得力不从心。

对于multipart请求,对于multipart格式的二进制数据会将一个表单拆分为多个部分(part),每个部分对应一个输入域。在一般的表单输入 域中它所对应的部分中会放置文本型数据,但是如果上传文件的话,它所对应的部分可以是二进制。

2、配置multipart解析器

从 Spring 3.1 开始,Spring 内置了两个 MultipartResolver 类的实现供我们选择:

1) CommonMultipartResolver:使用 Jakarta Commons FileUpload 解析 multipart 请求。

2)StandardServletMultipartResolver:依赖于 Servlet 3.0 对 multipart 请求的支持。

2.1 使用 Servlet 3.0 解析 multipart 请求(配置StandardServletMultipartResolver)

package com.spring.fileupload.config;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.servlet.DispatcherServlet;

public class FileUpLoadWebAppInitialzer implements WebApplicationInitializer{

    public void onStartup(ServletContext servletContext) throws ServletException {
        DispatcherServlet ds = new DispatcherServlet();
        Dynamic registration = servletContext.addServlet("appServlet", ds);
        registration.addMapping("/");
        registration.setMultipartConfig(
                new MultipartConfigElement("/temp/uploads"));
        
    }

}

2)如果我们配置 DispatcherServelt 的 Servlet 初始化类继承了 AbstractAnnotationConfigDispatcherServletInitilaizer 或

AbstractDispatcherServletInitializer 的话,我们可以通过重载 customizeRegistration() 方法来配置 multipart 的具体细节。

package com.spring.fileupload.config;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class FileUpLoadWebAppInitialzer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return new Class<?>[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        // TODO Auto-generated method stub
        return new Class<?>[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        // TODO Auto-generated method stub
        return new String[] { "/" };
    }

    @Override
    protected void customizeRegistration(Dynamic registration) {
        // TODO Auto-generated method stub
        new MultipartConfigElement("/temp/uploads");
    }
}

3)除了指定上传文件的临时目录外,我们还可以通过其他的构造器来配置 multipart 的具体细节,如:

(1) 限定上传文件的最大容量(以字节为单位),默认是没有限制的。

(2)限定整个 multipart 请求的最大容量(以字节为单位),默认是没有限制的。

(3)在上传的过程中,如果文件达到指定大小(以字节为单位),将会写入到临时文件路径中,默认为0。

2.2 配置 Jakarta Commons FileUpload multipart 解析器

package com.spring.fileupload.config;

import java.io.IOException;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
@ComponentScan("com.spring.fileupload")
public class WebConfig extends WebMvcConfigurerAdapter{
    
    @Bean
    public MultipartResolver multipartResolver() throws IOException {
        CommonsMultipartResolver multipartResolver = 
                new CommonsMultipartResolver();
        //设置临时目录路径
        multipartResolver.setUploadTempDir(new FileSystemResource("/temp/uploads"));
        //限定最大的文件容量为2MB
        multipartResolver.setMaxUploadSize(2097152);
        //限定最大的内存大小为0字节
        multipartResolver.setMaxInMemorySize(0);
        return multipartResolver;
    }
    
}

3、处理multipart请求

<!-- enctype属性设置告诉浏览器以multipart数据的形式提交表单 -->
    <form action="/uploadImg" enctype="multipart/form-data">
        <label>Upload Picture</label>
        <!-- accept属性设置将上传文件类型限制为JPEG,PNG以及GIF图片 -->
        <input type="file" name="picture" accept="image/jpeg,image/png,image/gif">        
    </form>

当表单提交时,我们编写的控制器方法就会接受上传的文件数据。

@RequestMapping(value="/uploadImg")
    public String uploadPicture(
            @RequestPart("picture") byte[] picture
            ) {
    
        return "success";
    }

相关推荐