Spring MVC 高级技术 - multipart数据处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yzy199391/article/details/89887029

multipart格式数据会将一个表单拆分为多个部分,每个部分对应一个输入域

配置multipart解析器

Spring内置multipart解析器

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

StandardServletMultipartResolver

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

上述代码完成了对StandardServletMultipartResolver的配置。

在Servlet中指定multipart的配置,来配置限制条件。我们必须在web.xml或Servlet初始化类中,将multipart的具体细节作为DispatcherServlet配置的一部分,如下所示:

public class MyServletInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        DispatcherServlet ds = new DispatcherServlet();
        ServletRegistration.Dynamic registration = servletContext.addServlet("appServlet", ds);
        registration.addMapping("/");
        registration.setMultipartConfig(new MultipartConfigElement("/tmp/"));
    }
}

对于继承了AbstractAnnotationConfigDispatcherServletInitializer或AbstractDispatcher-ServletInitializer的servlet初始化类,不需创建并注册DispatcherServlet,通过重载customizeRegistration(Dynamic registration)方法即可设置上述限制条件

MultipartConfigElement构造器,其所能接受的参数有:

  • maxFileSize:上传文件的最大容量(字节为单位),默认无限制;
  • maxRequestSize:multipart请求最大容量(字节为单位),默认无限制
  • fileSizeThreshold:指定最大容量(字节为单位),达到后文件写入临时文件路径,默认为0,即所有文件都会写入磁盘

eg:限制文件大小不超过2M,整个请求不超过4M,所有文件都要写到磁盘中。

@Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration){
        //设置MultipartConfigElement
        registration.setMultipartConfig(
                //设置上传文件的临时存储目录
                new MultipartConfigElement("/tmp/spittr/uploads", 2097152, 4094304, 0)
        );

CommonsMultipartResolver

一般不用,在Servlet版本较低时可用于替代上面resolver

@Bean
    public MultipartResolver multipartResolver() throws IOException {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(2097152);
        multipartResolver.setUploadTempDir(new FileSystemResource("/tmp/spittr/uploads"));
        multipartResolver.setMaxInMemorySize(0);
        return multipartResolver;
    }

处理multipart请求

原始byte[]形式

@PostMapping("/file")
    public String uploadFile(@RequestPart("profileFile") byte[] profileFile,
                           @Valid FileMode fileMode,
                           Errors errors) throws IOException {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;

        String path = "/Users/xmly/Desktop/";
        try {
            File dir = new File(path);
            if(!dir.exists() && dir.isDirectory()){
                dir.mkdirs();
            }
            File file = new File(path + fileMode.getName());
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(profileFile);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bos != null){
                try{
                    bos.close();
                }catch (IOException e1){
                    e1.printStackTrace();
                }
            }
            if(fos != null){
                try{
                    fos.close();
                }catch(IOException e2) {
                    e2.printStackTrace();
                }
            }
        }
        return "success";
    }

上述代码中,@RequestPart()注解指定的参数包含了请求中对应part的数据(文件内容),形式为byte[]。

MultipartFile形式

处理multipart数据的高级方式,为处理提供更丰富的对象。

@PostMapping("/file/multipart")
    public String uploadFile(@RequestParam("profileFile") MultipartFile profileFile,
                             HttpServletRequest request) throws IOException {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;

        try {
            //获取文件类型
            String type = profileFile.getContentType();
            //获取参数名
            String name = profileFile.getName();
            //获取文件名
            String originalName = profileFile.getOriginalFilename();

            String path = "/Users/xmly/Desktop/";

            File file = new File(path + originalName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            //获取文件内容
            bos.write(profileFile.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bos != null){
                try{
                    bos.close();
                }catch (IOException e1){
                    e1.printStackTrace();
                }
            }
            if(fos != null){
                try{
                    fos.close();
                }catch(IOException e2) {
                    e2.printStackTrace();
                }
            }
        }
        return "success";
    }

上述代码为使用MultipartFile类型数据接收上传文件数据的方式,还可以直接从request中获取,代码如下:

@PostMapping("/file/multipart/request")
    public String uploadFile3(HttpServletRequest request) throws IOException {
        StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();

        //判断是否为multipart请求
        if(resolver.isMultipart(request)){
            MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest)request;
            List<MultipartFile> list = multipartHttpServletRequest.getFiles("profileFile");
            list.forEach(file -> {
                BufferedOutputStream bos = null;
                FileOutputStream fos = null;

                try {
                    //获取文件类型
                    String type = file.getContentType();
                    String name = file.getName();
                    String originalName = file.getOriginalFilename();

                    String path = "/Users/xmly/Desktop/";

                    File file1 = new File(path + originalName);
                    fos = new FileOutputStream(file1);
                    bos = new BufferedOutputStream(fos);

                    bos.write(file.getBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if(bos != null){
                        try{
                            bos.close();
                        }catch (IOException e1){
                            e1.printStackTrace();
                        }
                    }
                    if(fos != null){
                        try{
                            fos.close();
                        }catch(IOException e2) {
                            e2.printStackTrace();
                        }
                    }
                }
            });
        }

        return "success";
    }

以part形式接收上传的文件

@PostMapping("/file/multipart")
    public String uploadFile2(@RequestParam("profileFile") Part profileFile){
    ...
    }

Part与MultipartFile接口差别不大;编写控制器时,若用Part来接受文件上传,则无需配置MultipartResolver。
其中包含的方法如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/yzy199391/article/details/89887029
今日推荐