@RequestParam和@RequestPart区别及Feign踩坑

概述

在做视频文件上传时遇到的问题,参考FileUploadException: the request was rejected because no multipart boundary was found。

@RequestParam

绝大多数人都知道RequestParam,看看源码:

/**
 * Annotation which indicates that a method parameter should be bound to a web
 * request parameter.
 *
 * 

Supported for annotated handler methods in Spring MVC and Spring WebFlux * as follows: *

    *
  • In Spring MVC, "request parameters" map to query parameters, form data, * and parts in multipart requests. This is because the Servlet API combines * query parameters and form data into a single map called "parameters", and * that includes automatic parsing of the request body. *
  • In Spring WebFlux, "request parameters" map to query parameters only. * To work with all 3, query, form data, and multipart data, you can use data * binding to a command object annotated with {@link ModelAttribute}. *
* *

If the method parameter type is {@link Map} and a request parameter name * is specified, then the request parameter value is converted to a {@link Map} * assuming an appropriate conversion strategy is available. * *

If the method parameter is {@link java.util.Map Map<String, String>} or * {@link org.springframework.util.MultiValueMap MultiValueMap<String, String>} * and a parameter name is not specified, then the map parameter is populated * with all request parameter names and values. */ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestParam { }

使用@RequestParam可以应付绝大多数场景(99.99%,4个9),这也是开发5年来并没注意到RequestPart的原因?

@RequestPart

今天第一次注意到这个注解:

/**
 * Annotation that can be used to associate the part of a "multipart/form-data" request
 * with a method argument.
 *
 * 

Supported method argument types include MultipartFile in conjunction with * Spring's MultipartResolver abstraction, {@code javax.servlet.http.Part} in * conjunction with Servlet 3.0 multipart requests, or otherwise for any other method * argument, the content of the part is passed through an HttpMessageConverter * taking into consideration the 'Content-Type' header of the request part. This is * analogous to what @RequestBody does to resolve an argument based on the * content of a non-multipart regular request. * *

Note that @RequestParam annotation can also be used to associate the part * of a "multipart/form-data" request with a method argument supporting the same method * argument types. The main difference is that when the method argument is not a String * or raw MultipartFile / Part, {@code @RequestParam} relies on type * conversion via a registered Converter or PropertyEditor while * {@link RequestPart} relies on {@link HttpMessageConverter HttpMessageConverters} * taking into consideration the 'Content-Type' header of the request part. * {@link RequestParam} is likely to be used with name-value form fields while * {@link RequestPart} is likely to be used with parts containing more complex content * e.g. JSON, XML). */ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestPart { }

区别

Note that @RequestParam annotation can also be used to associate the part of a “multipart/form-data” request with a method argument supporting the same method argument types. The main difference is that when the method argument is not a String or raw MultipartFile / Part, @RequestParam relies on type conversion via a registered Converter or PropertyEditor while RequestPart relies on HttpMessageConverter HttpMessageConverters taking into consideration the ‘Content-Type’ header of the request part. @RequestParam is likely to be used with name-value form fields while @RequestPart is likely to be used with parts containing more complex content.

翻译:
注意到,@RequestParam注解还可以用于将multipart/form data请求的部分与支持相同方法参数类型的方法参数相关联。区别在于,当方法参数不是字符串或原始多部分文件/部分时,@RequestParam依赖于通过注册的转换器或PropertyEditor进行的类型转换,而RequestPart依赖于HttpMessageConverterHTTP消息转换器,同时考虑到请求部分的“Content type”头@RequestParam可能与name-value表单字段一起使用,而@RequestPart可能与包含更复杂内容的部分一起使用。

解释:
@RequestPart主要用来处理content-type为multipart/form-datamultipart/mixed stream发起的请求,可以获取请求中的参数,包括普通文本、文件或复杂对象比如JSON、XML等,针对复杂对象,需要明确对应的content-type。

@RequestParam默认主要来处理query parameters, form data,and parts in multipart requests, 且是 key-value键值对这种文本,要区分

Spring MVC:

会把query parameters, form data,and parts in multipart requests 里面的参数组合到一起存放在一个参数Map里(key相同的参数,值会追加)

Spring WebFlux:

只会处理query parameters

@RequestPart这个注解用在multipart/form-data表单提交请求的方法上。
2.支持的请求方法的方式MultipartFile,属于Spring的MultipartResolver类。这个请求是通过http协议传输的。
3.@RequestParam也同样支持multipart/form-data请求。
4.他们最大的不同是,当请求方法的请求参数类型不再是String类型的时候。
5.@RequestParam适用于name-valueString类型的请求域,@RequestPart适用于复杂的请求域(像JSON,XML)

1 @RequestParam适用于name-value表单字段,而@RequestPart经常被用于处理复杂内容(例如JSON, XML) 2 当方法的参数类型不是String或者原生的MultipartFile / Part,@RequstParam需要注册并使用 Converter or PropertyEditor 进行类型转换,而 RequestPart 可通过请求体中的“Content-Type“进行使用 HttpMessageConverters转换

RequestPart 注解会生成临时文件,而RequestParam 则不会生成临时文件,效率上 ReqeustParam 会比 RequestPart 快一个数量级

你可能感兴趣的:(@RequestParam和@RequestPart区别及Feign踩坑)