• [第二章—Spring MVC的高级技术] 2.2 置multipart解析器


    使用Servlet 3.0解析multipart请求

    兼容Servlet 3.0的StandardServletMultipartResolver没有构 造器参数,也没有要设置的属性。


    这样,在Spring应用上下文中,将 其声明为bean就会非常简单,如下所示:


    file

    ● 既然这个@Bean方法如此简单,你可能就会怀疑。

      ○ 我们到底该如何限制StandardServletMultipartResolver的工作方式呢。
      ○ 如果我们想要限制用户上传文件的大小,该怎么实现?
      ○ 如果我们想要指定文件在上传时临时写入目录的位置,又该如何实现?
    • 1
    • 2

    因为没有属性和构造器参数,StandardServletMultipartResolver的功能看起来似乎有些受限。


    实际上,并不是这样,我们是有办法配置StandardServletMultipartResolver的限制条件的。


    具体来说,我们必须要在web.xml或Servlet初始化类中将multipart的具体细节作为DispatcherServlet配置的一部分。

    如果我们采用Servlet初始化类的方式来配置DispatcherServlet,这个初始化类应该已经实现了WebApplicationInitializer。那么我们可以在Servlet registration上调用setMultipartConfig()方法,传入一个MultipartConfigElement实例。 以下是最基本的DispatcherServlet multipart配置,它将临时路径设置为"/tmp/spittr/uploads":

    
        multipart-config-location
        /tmp/spittr/uploads
    
    • 1
    • 2
    • 3
     DispatcherServlet ds = new DispatcherServlet();
     ServletRegistration.Dynamic registration = servletContext.addServlet("appServlet", ds);
     registration.addMapping("/");
    registration.setMultipartConfig(new MultipartConfigElement("/tmp/spittr/uploads"));
    • 1
    • 2
    • 3

    如果我们配置DispatcherServlet的Servlet初始化类继承了两个类。

    ● AbstractAnnotationConfigDispatcherServletInitializer
    ● AbstractDispatcher-ServletInitializer
    ·```
     那么我们不会直接创建DispatcherServlet实例并将其注册到Servlet上下文中。这样的话,将不会有对Dynamic Servletregistration的引用供我们使用了。
    ***
    但是,我们可以通过重载customizeRegistration () 方法 (它会得到一个Dynamic作为参数) 来配置multipart的具体细节:
    ```java
    protected void customizeRegistration(Dyamic  registration){
        registration.setMultipartConfig(new MultipartConfigElement("/tmp/spittr/uploads"));
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    到目前为止,我们所使用的是只有一个参数的MultipartConfigElement构造器,这个参数指定的是文件系统中的一个绝对目录,上传文件将会临时写入该目录中。

    在上传的过程中,如果文件大小达到了一个指定的最大容量(以字节为单位),将会写入到临时文件路径中。默认值为0,也就是所有上传的文件都会写入到磁盘上。


    例如,假设我们想要限制文件的大小不超过2MB,整个请求不超过4MB,而且所有的文件都要写到磁盘中。 下面的代码使用MultipartConfigElement设置了这些临界值:

    MultipartConfigElement multipartConfig = new MultipartConfigElement("/tmp/spittr/uploads", 2097152, 4194304, 0);
    
    @override
    protected void customizeRegistration(Dynamic regisation){
        registration.setMultpartConfig(new MultipartConfigElement("/tmp/spittr/uploads",2097152,4194304,0));
    }
    • 1
    • 2
    • 3
    • 4
    • 5

    如果我们使用更为传统的web.xml来配置MultipartConfigElement的话,那么可以使用 中 的 元素,如下所示: 的默认值与MultipartConfigElement相 同。与MultipartConfigElement一样,必须要配置的是 。


    配置Jakarta Commons FileUpload multipart解析器

    1. 介绍StandardServletMultipartResolver是一个不错的选择。
    2. 如果需要在非Servlet 3.0的容器中部署应用,则需要替代方案。
    3. 可以编写自己的MultipartResolver实现,但除非需要执行特定逻辑,否则没有必要这样做。
    4. Spring内置了CommonsMultipartResolver,可以作为StandardServletMultipartResolver的替代方案
    • 1
    • 2
    • 3

    将CommonsMultipartResolver声明为Spring bean的最简单方式如下:

    @Bean
    public CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        // 设置解析器的相关属性
        resolver.setMaxUploadSize(5242880); // 5MB
        resolver.setMaxInMemorySize(4096); // 4KB
        return resolver;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    与StandardServletMultipartResolver有所不同,CommonsMultipart-Resolver不会强制要求设置临时文件路 径。默认情况下,这个路径就是Servlet容器的临时目录。 @Bean public MultipartResolver multipartResolver(){ retrun new CommonsMultpartResolver(); } 通过 设置uploadTempDir属性,我们可以将其指定为一个不同的位置:

    @Bean
    public MultipartAReslover multpartReslover() throws  IOException{
       CommonsMultipartReslover multiparReslover = new CommonsMultipartReslover();
       multipartReslover.setUploadTempDir(new fileSystemResources("/tmp/spittr/uploads"));
       return multipartResolver;
    }
    • 1
    • 2
    • 3
    • 4
    • 5

    实际上,我们可以按照相同的方式指定其他的multipart上传细节,也 就是设置CommonsMultipartResolver的属性。 例如,如下的配 置就等价于我们在前文通过MultipartConfigElement所配置的 StandardServletMultipartResolver:

    @Bean
    public MultipartAReslover multpartReslover() throws  IOException{
       CommonsMultipartReslover multiparReslover = new CommonsMultipartReslover();
       multipartReslover.setUploadTempDir(new fileSystemResources("/tmp/spittr/uploads"));
       multipartReslover.setMaxUploadSize(2097152);
       multipartReslover.serMaxInMemorySize(0);
       return multipartResolver;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里,我们将最大的文件容量设置为2MB,最大的内存大小设置为 0字节。这两个属性直接对应于MultipartConfigElement的第二 个和第四个构造器参数,表明不能上传超过2MB的文件,并且不管文 件的大小如何,所有的文件都会写到磁盘中。 但是与MultipartConfigElement有所不同,我们无法设定multipart请 求整体的最大容量。

    本文由博客一文多发平台 OpenWrite 发布!

  • 相关阅读:
    实时操作系统(RTOS)指南
    从Langchain到ReAct,在大模型时代下全新的应用开发核心
    【Node.JS 】创建基本的web服务器
    最新Win11安装安卓子系统详细教程
    vue jsx 封装Table 表格+Tree 树形控件 jsx自定义el-table-column
    java八股文面试[数据库]——MySQL的体系架构
    PD3.1详解 第二章(EPR)
    对于云原生时代的后端业务开发和项目系统学习,选Go Or Java?
    【flink-sql实战】flink 主键声明与upsert功能实战
    C++:类与对象(3)
  • 原文地址:https://blog.csdn.net/weixin_44385781/article/details/134257446