Spring MVC 处理文件上传

简介: 使用 HttpServletRequest 对象处理上传文件

使用 HttpServletRequest 对象处理上传文件



@RequestMapping(value = "/fileUpload", method = RequestMethod.POST)
    @ResponseBody
    public String fileUpload(HttpServletRequest request) {
        log.info("----fileUpload start----");
        log.info("className = {}, contextPath = {}, servletPath = {}", request.getClass().getName(), request.getContextPath(), request.getServletPath());
        final Map<String, String[]> parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            log.info("key = {}, value = {}", entry.getKey(), Arrays.toString(entry.getValue()));
        }
        final MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
        for (Map.Entry<String, List<MultipartFile>> entry : multipartHttpServletRequest.getMultiFileMap().entrySet()) {
            final List<MultipartFile> value = entry.getValue();
            for (MultipartFile file : value) {
                log.info("fileName = {}, fileOriginalFilename = {}, size = {} KB", file.getName(), file.getOriginalFilename(), file.getSize() / 1024);
            }
        }
        log.info("----fileUpload end----");
        return "upload successful";
    }


对应 cURL 描述

curl --location --request POST 'localhost:4000/fileUpload' \
--form 'aaa="bbb"' \
--form 'def=@"/C:/Users/hp/Desktop/11111.sql"'


对应的 RestTemplate 描述

public String uploadTest() {
        log.info("--- uploadTest start ---");
        HttpHeaders headers = new HttpHeaders();
        //  请勿轻易改变此提交方式,大部分的情况下,提交方式都是表单提交
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        //  封装参数,千万不要替换为 Map 与 HashMap,否则参数无法传递
        MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        multiValueMap.add("aaa", "bbb");
        multiValueMap.add("def", new FileSystemResource("C:/Users/hp/Desktop/11111.sql"));
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(multiValueMap, headers);
        // 执行HTTP请求
        ResponseEntity<String> response = null;
        try {
            response = this.restTemplate.exchange("http://localhost:4000/fileUpload", HttpMethod.POST, requestEntity, String.class);
        } catch (HttpStatusCodeException e) {
            final HttpStatus httpStatus = e.getStatusCode();
            log.error("HttpStatusCodeException httpStatus = {}", httpStatus, e);
        } catch (RestClientException e) {
            log.error("RestClientException", e);
        }
        if (response != null) {
            //  输出结果
            final HttpStatus statusCode = response.getStatusCode();
            final int value = statusCode.value();
            log.info("rest template statusCode = {}, result = {}", value, response.getBody());
        }
        log.info("--- uploadTest end ---");
        return "OK";
    }


日志打印结果

2021-05-06 18:44:42.849  controller.EmailController   : ----fileUpload start----
2021-05-06 18:44:42.849  controller.EmailController   : className = org.springframework.web.multipart.support.StandardMultipartHttpServletRequest, contextPath = , servletPath = /fileUpload
2021-05-06 18:44:42.849  controller.EmailController   : key = aaa, value = [bbb]
2021-05-06 18:44:42.850  controller.EmailController   : fileName = def, fileOriginalFilename = 11111.sql, size = 2 KB
2021-05-06 18:44:42.850  controller.EmailController   : ----fileUpload end----


直接使用 MultipartFile  对象获取上传的文件



@RequestMapping("/multipartFile")
    public String upload(@RequestParam("aaa") String abc, @RequestParam("def") MultipartFile file) throws IllegalStateException {
        log.info("abc = {}", abc);
        // 判断文件是否为空,空则返回失败页面
        if (file.isEmpty()) {
            return "failed";
        }
        log.info("className = {}, fileName = {}, fileOriginalFilename = {}, size = {} KB", file.getClass().getName(), file.getName(), file.getOriginalFilename(), file.getSize() / 1024);
        return "success";
    }


日志输出

2021-05-06 20:06:36.578  INFO 3488 --- [nio-4000-exec-1] c.lagou.edu.controller.EmailController   : abc = bbb
2021-05-06 20:06:36.581  INFO 3488 --- [nio-4000-exec-1] c.lagou.edu.controller.EmailController   : className = org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile, fileName = def, fileOriginalFilename = 11111.sql, size = 2 KB


由此说明 MultipartFile 的实际类型为


org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile


多文件上传,将 MultipartFile 改为类型数组即可


In our example we are presenting demo for single and multiple file upload. So we have created two different methods for uploading the file. In single upload, the method should have the parameter as below with other parameters.

@RequestParam("file") MultipartFile file

And for multiple file upload , the parameter should be as below

@RequestParam("file") MultipartFile[]  file


代码片段


package com.lagou.edu.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
 * 测试 spring mvc fileUpload
 *
 * @author lik
 * @date 2021/5/6
 */
@Slf4j
@RestController
public class EmailController {
    @Autowired
    RestTemplate restTemplate;
    @RequestMapping(value = "/uploadTest")
    public String uploadTest() {
        log.info("--- uploadTest start ---");
        HttpHeaders headers = new HttpHeaders();
        //  请勿轻易改变此提交方式,大部分的情况下,提交方式都是表单提交
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        //  封装参数,千万不要替换为 Map 与 HashMap,否则参数无法传递
        MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        multiValueMap.add("aaa", "bbb");
        multiValueMap.add("def", new FileSystemResource("C:/Users/hp/Desktop/11111.sql"));
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(multiValueMap, headers);
        // 执行HTTP请求
        ResponseEntity<String> response = null;
        try {
            response = this.restTemplate.exchange("http://localhost:4000/fileUpload", HttpMethod.POST, requestEntity, String.class);
        } catch (HttpStatusCodeException e) {
            final HttpStatus httpStatus = e.getStatusCode();
            log.error("HttpStatusCodeException httpStatus = {}", httpStatus, e);
        } catch (RestClientException e) {
            log.error("RestClientException", e);
        }
        if (response != null) {
            //  输出结果
            final HttpStatus statusCode = response.getStatusCode();
            final int value = statusCode.value();
            log.info("rest template statusCode = {}, result = {}", value, response.getBody());
        }
        log.info("--- uploadTest end ---");
        return "OK";
    }
    @RequestMapping(value = "/fileUpload", method = RequestMethod.POST)
    @ResponseBody
    public String fileUpload(HttpServletRequest request) {
        log.info("----fileUpload start----");
        log.info("className = {}, contextPath = {}, servletPath = {}", request.getClass().getName(), request.getContextPath(), request.getServletPath());
        final Map<String, String[]> parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            log.info("key = {}, value = {}", entry.getKey(), Arrays.toString(entry.getValue()));
        }
        final MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
        for (Map.Entry<String, List<MultipartFile>> entry : multipartHttpServletRequest.getMultiFileMap().entrySet()) {
            final List<MultipartFile> value = entry.getValue();
            for (MultipartFile file : value) {
                log.info("className = {}, fileName = {}, fileOriginalFilename = {}, size = {} KB", file.getClass().getName(), file.getName(), file.getOriginalFilename(), file.getSize() / 1024);
            }
        }
        log.info("----fileUpload end----");
        return "upload successful";
    }
    @RequestMapping("/multipartFile")
    public String upload(@RequestParam("aaa") String abc, @RequestParam("def") MultipartFile file) throws IllegalStateException {
        log.info("abc = {}", abc);
        // 判断文件是否为空,空则返回失败页面
        if (file.isEmpty()) {
            return "failed";
        }
        log.info("className = {}, fileName = {}, fileOriginalFilename = {}, size = {} KB", file.getClass().getName(), file.getName(), file.getOriginalFilename(), file.getSize() / 1024);
        return "success";
    }
    @RequestMapping("/multipartFiles")
    public String upload(@RequestParam("def") MultipartFile[] multipartFiles) throws IllegalStateException {
        for (MultipartFile file : multipartFiles) {
            log.info("className = {}, fileName = {}, fileOriginalFilename = {}, size = {} KB", file.getClass().getName(), file.getName(), file.getOriginalFilename(), file.getSize() / 1024);
        }
        return "success";
    }
}


参考



一个包含各Java 教程的网站:Java, Spring, Angular, Hibernate and Android


https://www.concretepage.com/




目录
相关文章
|
29天前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
8月前
|
前端开发 Java 测试技术
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestParam
本文介绍了 `@RequestParam` 注解的使用方法及其与 `@PathVariable` 的区别。`@RequestParam` 用于从请求中获取参数值(如 GET 请求的 URL 参数或 POST 请求的表单数据),而 `@PathVariable` 用于从 URL 模板中提取参数。文章通过示例代码详细说明了 `@RequestParam` 的常用属性,如 `required` 和 `defaultValue`,并展示了如何用实体类封装大量表单参数以简化处理流程。最后,结合 Postman 测试工具验证了接口的功能。
454 0
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestParam
|
8月前
|
JSON 前端开发 Java
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestBody
`@RequestBody` 是 Spring 框架中的注解,用于将 HTTP 请求体中的 JSON 数据自动映射为 Java 对象。例如,前端通过 POST 请求发送包含 `username` 和 `password` 的 JSON 数据,后端可通过带有 `@RequestBody` 注解的方法参数接收并处理。此注解适用于传递复杂对象的场景,简化了数据解析过程。与表单提交不同,它主要用于接收 JSON 格式的实体数据。
698 0
|
8月前
|
前端开发 Java 微服务
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@PathVariable
`@PathVariable` 是 Spring Boot 中用于从 URL 中提取参数的注解,支持 RESTful 风格接口开发。例如,通过 `@GetMapping(&quot;/user/{id}&quot;)` 可以将 URL 中的 `{id}` 参数自动映射到方法参数中。若参数名不一致,可通过 `@PathVariable(&quot;自定义名&quot;)` 指定绑定关系。此外,还支持多参数占位符,如 `/user/{id}/{name}`,分别映射到方法中的多个参数。运行项目后,访问指定 URL 即可验证参数是否正确接收。
449 0
|
8月前
|
JSON 前端开发 Java
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestMapping
@RequestMapping 是 Spring MVC 中用于请求地址映射的注解,可作用于类或方法上。类级别定义控制器父路径,方法级别进一步指定处理逻辑。常用属性包括 value(请求地址)、method(请求类型,如 GET/POST 等,默认 GET)和 produces(返回内容类型)。例如:`@RequestMapping(value = &quot;/test&quot;, produces = &quot;application/json; charset=UTF-8&quot;)`。此外,针对不同请求方式还有简化注解,如 @GetMapping、@PostMapping 等。
397 0
|
8月前
|
JSON 前端开发 Java
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RestController
本文主要介绍 Spring Boot 中 MVC 开发常用的几个注解及其使用方式,包括 `@RestController`、`@RequestMapping`、`@PathVariable`、`@RequestParam` 和 `@RequestBody`。其中重点讲解了 `@RestController` 注解的构成与特点:它是 `@Controller` 和 `@ResponseBody` 的结合体,适用于返回 JSON 数据的场景。文章还指出,在需要模板渲染(如 Thymeleaf)而非前后端分离的情况下,应使用 `@Controller` 而非 `@RestController`
308 0
|
4月前
|
前端开发 Java API
Spring Cloud Gateway Server Web MVC报错“Unsupported transfer encoding: chunked”解决
本文解析了Spring Cloud Gateway中出现“Unsupported transfer encoding: chunked”错误的原因,指出该问题源于Feign依赖的HTTP客户端与服务端的`chunked`传输编码不兼容,并提供了具体的解决方案。通过规范Feign客户端接口的返回类型,可有效避免该异常,提升系统兼容性与稳定性。
307 0
|
4月前
|
SQL Java 数据库连接
Spring、SpringMVC 与 MyBatis 核心知识点解析
我梳理的这些内容,涵盖了 Spring、SpringMVC 和 MyBatis 的核心知识点。 在 Spring 中,我了解到 IOC 是控制反转,把对象控制权交容器;DI 是依赖注入,有三种实现方式。Bean 有五种作用域,单例 bean 的线程安全问题及自动装配方式也清晰了。事务基于数据库和 AOP,有失效场景和七种传播行为。AOP 是面向切面编程,动态代理有 JDK 和 CGLIB 两种。 SpringMVC 的 11 步执行流程我烂熟于心,还有那些常用注解的用法。 MyBatis 里,#{} 和 ${} 的区别很关键,获取主键、处理字段与属性名不匹配的方法也掌握了。多表查询、动态
147 0
|
4月前
|
JSON 前端开发 Java
第05课:Spring Boot中的MVC支持
第05课:Spring Boot中的MVC支持
246 0
|
10月前
|
SQL Java 数据库连接
对Spring、SpringMVC、MyBatis框架的介绍与解释
Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
505 29