• Spring 4 官方文档学习(十一)Web MVC 框架之multipart(文件上传)支持


    http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-multipart

    1、简介

    Spring内置的multipart支持会处理web应用中的文件上传。你可以启用该支持 -- 通过可插拔的MultipartResolver对象们,它们都是定义在 org.springframework.web.multipart 包中。Spring提供了一个MultipartResolver实现,配合Commons FileUpload使用,或者配合Servlet 3.0 multipart 请求解析使用。

    默认,Spring不会处理multipart,因为一些开发者希望由自己来处理它们。你可以让Spring来处理 -- 通过在web应用的context中添加一个multipart resolver。每个请求都会被检查,以查看其是否包含一个multipart。如果没有,就放行。如果有,在你的上下文中声明的MultipartResolver会被用来处理它。之后,你就可以像对待其他attribute一样来对待在你请求中的multipart attribute。

    2、结合Commons FileUpload来使用MultipartResolver

    下例示意了如何使用CommonsMultipartResolver:

    <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    
        <!-- one of the properties available; the maximum file size in bytes -->
        <property name="maxUploadSize" value="100000"/>
    
    </bean>

    当然,你还要将需要的jars放到你的classpath内,这样才能使其正常工作。在该例中,你需要使用 commons-fileupload.jar 。

    当Spring DispatcherServlet 探测到一个multi-part请求时,它会激活已声明的resolver,并将请求交给它。该resolver会将当前的HttpServletRequest封装进一个MultipartHttpServletRequest,后者支持multipart file uploads。通过使用MultipartHttpServletRequest,你可以在controllers中获取包含在该请求中的multiparts的信息,还可以实际访问到这些multipart files。

    3、结合Servlet 3.0 来使用MultipartResolver

    为了使用基于Servlet 3.0 的multipart解析,你需要给DispatcherServlet标记一个”multipart-config”部分 -- 在xml中,或者,在编码式Servlet注册中标记一个javax.servlet.MultipartConfigElement,或者,在自定义Servlet class情况下,使用javax.servlet.annotation.MultipartConfig注解。 配置设置,例如最大尺寸或者存储位置,需要在该Servlet注册级别上应用,因为Servlet 3.0 不允许这些设置由MultipartResolver来完成!

    一旦Servlet 3.0 multipart解析被启用了,你就可以将StandardServletMultipartResolver添加到你的Spring配置中:

    <bean id="multipartResolver"
            class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
    </bean>

    4、处理form中的文件上传

    首先,创建一个form带有file input,允许用户上传。encoding attribute (enctype=”multipart/form-data”)会告诉浏览器将forms以multipart request形式编码:

    <html>
        <head>
            <title>Upload a file please</title>
        </head>
        <body>
            <h1>Please upload a file</h1>
            <form method="post" action="/form" enctype="multipart/form-data">
                <input type="text" name="name"/>
                <input type="file" name="file"/>
                <input type="submit"/>
            </form>
        </body>
    </html>

    下一步就是创建一个controller来处理该文件上传。 如下:

    @Controller
    public class FileUploadController {
    
        @PostMapping("/form")
        public String handleFormUpload(@RequestParam("name") String name,
                @RequestParam("file") MultipartFile file) {
    
            if (!file.isEmpty()) {
                byte[] bytes = file.getBytes();
                // store the bytes somewhere
                return "redirect:uploadSuccess";
            }
    
            return "redirect:uploadFailure";
        }
    
    }

    注意@RequestParam 参数会映射到form中声明的input元素。在该例中,没有涉及byte[],但你仍然可以将其保存到数据库、文件系统等等。

    当使用Servlet 3.0 multipart 解析时,你还可以使用javax.servlet.http.Part:

    @Controller
    public class FileUploadController {
    
        @PostMapping("/form")
        public String handleFormUpload(@RequestParam("name") String name,
                @RequestParam("file") Part file) {
    
            InputStream inputStream = file.getInputStream();
            // store bytes from uploaded file somewhere
    
            return "redirect:uploadSuccess";
        }
    
    }

    5、处理来自编码式客户端的文件上传请求

    multipart请求还可以来自非浏览器的客户端 -- 在REST风格式服务场景中。所有上述例子和配置均适用于这种情况。 然而,不同于浏览器,编码式客户端也可以发送特定内容类型的更加复杂的数据 -- 例如,一个multipart请求带有一个文件和JSON格式的数据:

    POST /someUrl
    Content-Type: multipart/mixed
    
    --edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
    Content-Disposition: form-data; name="meta-data"
    Content-Type: application/json; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    {
        "name": "value"
    }
    --edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
    Content-Disposition: form-data; name="file-data"; filename="file.properties"
    Content-Type: text/xml
    Content-Transfer-Encoding: 8bit
    ... File Data ...

    你可以使用@RequestParam(“meta-data”) String metadata 来访问 "meta-data"部分。然而,你可能倾向于接收一个强类型的对象 -- 由请求中的JSON格式数据初始化而成的,非常类似于@RequestBody使用HttpMessageConverter将一个non-multipart请求的请求体转成目标对象。

    此时,你可以使用@RequestPart注解来代替@RequestParam注解。它允许你再来关注一个经过HttpMessageConverter的特定的multipart内容其'Content-Type' header部分。

    @PostMapping("/someUrl")
    public String onSubmit(@RequestPart("meta-data") MetaData metadata,
            @RequestPart("file-data") MultipartFile file) {
    
        // ...
    
    }

    注意MultipartFile 可以被@RequestParam或@RequestPart任意访问。然而, @RequestPart(“meta-data”) MetaData在这里,是读取其'Content-Type' header部分的JSON内容,并使用MappingJackson2HttpMessageConverter来转换的。

  • 相关阅读:
    前端程序员容易忽视的一些基础知识
    一道前端学习题
    Unity调用Windows对话框保存时另存为弹框
    Unity镜子效果的实现(无需镜子Shader)
    Unity射线检测的用法总结
    unity中实现简单对象池,附教程原理
    Unity调用Window提示框Yes/No(英文提示窗)
    Unity调用Windows弹框、提示框(确认与否,中文)
    C#LinQ语法
    服务器的购买与网站的创建
  • 原文地址:https://www.cnblogs.com/larryzeal/p/6139470.html
Copyright © 2020-2023  润新知