@RequestBody MultiValueMap 不支持内容类型 'application/x-www-form-urlencoded;charset=UTF-8'
Posted
技术标签:
【中文标题】@RequestBody MultiValueMap 不支持内容类型 \'application/x-www-form-urlencoded;charset=UTF-8\'【英文标题】:Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported for @RequestBody MultiValueMap@RequestBody MultiValueMap 不支持内容类型 'application/x-www-form-urlencoded;charset=UTF-8' 【发布时间】:2016-02-21 03:25:20 【问题描述】:基于for problem with x-www-form-urlencoded with Spring @Controller的答案
我已经写了下面的@Controller方法
@RequestMapping(value = "/email/authenticate", method = RequestMethod.POST
, produces = "application/json", "application/xml"
, consumes = "application/x-www-form-urlencoded"
)
public
@ResponseBody
Representation authenticate(@PathVariable("email") String anEmailAddress,
@RequestBody MultiValueMap paramMap)
throws Exception
if(paramMap == null || paramMap.get("password") == null)
throw new IllegalArgumentException("Password not provided");
请求失败并出现以下错误
"timestamp": 1447911866786,
"status": 415,
"error": "Unsupported Media Type",
"exception": "org.springframework.web.HttpMediaTypeNotSupportedException",
"message": "Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported",
"path": "/users/usermail%40gmail.com/authenticate"
[PS:Jersey 更加友好,但由于这里的实际限制,现在无法使用它]
【问题讨论】:
你在@RequestBody 中添加了consumes = "application/x-www-form-urlencoded" 吗? 你是如何执行请求的?添加 (js,jquery, curl 或任何你使用的) 的代码。 我也有同样的问题。就我而言,我使用 jquery ajax 发布数据,数据为JSON.stringify("ordersToDownload":"00417002"
这是我使用的代码:$.ajax(url:"/myurl", type:"POST", data: JSON.stringify("someAttribute":"someData") )
查看我的答案enter link description here
【参考方案1】:
问题是当我们使用 application/x-www-form-urlencoded 时,Spring 并不将其理解为 RequestBody。所以,如果我们想使用这个 我们必须删除 @RequestBody 注释。
然后尝试以下操作:
@RequestMapping(value = "/email/authenticate", method = RequestMethod.POST,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_ATOM_XML_VALUE, MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody Representation authenticate(@PathVariable("email") String anEmailAddress, MultiValueMap paramMap) throws Exception
if(paramMap == null && paramMap.get("password") == null)
throw new IllegalArgumentException("Password not provided");
return null;
注意去掉了注释@RequestBody
回答:Http Post request with content type application/x-www-form-urlencoded not working in Spring
【讨论】:
谢谢!解决问题。现在我想知道我们如何明确删除application/x-www-form-urlencoded
?
没有必要@kholofeloMaloma
如果有人想知道为什么这在没有任何注释的情况下工作,似乎 Spring 处理任何未注释的参数就好像它们有 @ModelAttribute, even though this behaviour is (sadly) not documented. And
@ModelAttribute 确实理解 x-www-form-urlencoded
public ResponseEntity> getToken(MultiValueMap paramMap) IllegalArgumentException: 参数类型不匹配
感谢您的信息!作为一个新手,我想知道 Spring 解析有效负载并将其绑定到对象的这种奇怪行为背后的原因是什么?【参考方案2】:
看来现在你可以用@RequestParam
标记方法参数,它会为你完成这项工作。
@PostMapping( "some/request/path" )
public void someControllerMethod( @RequestParam Map<String, String> body )
//work with Map
【讨论】:
这在 Spring Boot 2.4.2 上有效【参考方案3】:在您的请求中添加标头以将内容类型设置为 application/json
curl -H 'Content-Type: application/json' -s -XPOST http://your.domain.com/ -d YOUR_JSON_BODY
这样spring就知道如何解析内容了。
【讨论】:
您可能还需要在命令中添加 Accept 标头:'curl -vk -H "Accept: application/json" -H "Content-Type: application/json" ' etc.跨度> 您能解释一下如何将此设置添加到我的 html 表单吗?【参考方案4】:在春天 5
@PostMapping( "some/request/path" )
public void someControllerMethod( @RequestParam MultiValueMap body )
// import org.springframework.util.MultiValueMap;
String datax = (String) body .getFirst("datax");
【讨论】:
是的,在映射中包含 consumer=MediaType.APPLICATION_FORM_URLENCODED_VALUE,您应该得到更多积分,先生!谢谢!从请求中获取 MultiValueMap 现在需要 @RequestParam 接缝【参考方案5】:@RequestBody MultiValueMap 参数映射
在这里删除@RequestBody注释
@RequestMapping(value = "/signin",method = RequestMethod.POST)
public String createAccount(@RequestBody LogingData user)
logingService.save(user);
return "login";
@RequestMapping(value = "/signin",method = RequestMethod.POST)
public String createAccount( LogingData user)
logingService.save(user);
return "login";
这样
【讨论】:
虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的回答添加解释并说明适用的限制和假设。【参考方案6】:只需去掉@RequestBody
注解即可解决问题(在Spring Boot 2上测试):
@RestController
public class MyController
@PostMapping
public void method(@Valid RequestDto dto)
// method body ...
【讨论】:
【参考方案7】:我在this *** answer 中写了一个替代方案。
那里我一步一步写,用代码解释。捷径:
首先:写一个对象
第二个:创建一个转换器来映射扩展AbstractHttpMessageConverter的模型
第三:告诉spring使用这个转换器实现一个覆盖configureMessageConverters方法的WebMvcConfigurer.class
第四个也是最后一个:在控制器内部的映射中使用此实现设置,在对象前面使用 = MediaType.APPLICATION_FORM_URLENCODED_VALUE 和 @RequestBody。
我正在使用 Spring Boot 2。
【讨论】:
【参考方案8】:当我想处理 简单的 HTML 表单提交(不使用使用 thymeleaf 或 Spring 的表单标签时,我遇到了同样的问题) 在 Spring MVC 中。
Douglas Ribeiro 的回答会很好用。但以防万一,对于像我这样真正想在 Spring MVC 中使用“@RequestBody”的任何人。
这是问题的原因:
Spring需要①识别“Content-Type”,②转换 内容添加到我们在方法签名中声明的参数类型。 “application/x-www-form-urlencoded”不支持,因为,由 默认,Spring找不到合适的HttpMessageConverter来做 转换工作,即步骤②。解决方案:
我们手动在 Spring 中添加一个适当的 HttpMessageConverter 我们的应用程序的配置。步骤:
-
选择我们要使用的 HttpMessageConverter 类。为了
'application/x-www-form-urlencoded',我们可以选择
“org.springframework.http.converter.FormHttpMessageConverter”。
将 FormHttpMessageConverter 对象添加到 Spring 的配置中,
通过调用“公共空白
configureMessageConverters(List
顺便说一句,我们可以使用“@RequestParam”访问值的原因是:
根据 Servlet 规范(第 3.1.1 节):
以下是post form之前必须满足的条件 数据将填充到参数集:请求是 HTTP 或 HTTPS 请求。 2. HTTP 方法是POST。 3.内容类型为 应用程序/x-www-form-urlencoded。 4. servlet 进行了初始化 对 request 调用任何 getParameter 系列方法 对象。
因此,请求正文中的值将被填充到参数中。但是在 Spring 中,您仍然可以访问 RequestBody,即使您可以在 同一方法的签名处使用 @RequstBody 和 @RequestParam强>。 喜欢:
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String processForm(@RequestParam Map<String, String> inputValue, @RequestBody MultiValueMap<String, List<String>> formInfo)
......
......
inputValue 和 formInfo 包含相同的数据,“@RequestParam”的类型除外是Map,而“@RequestBody" 是 MultiValueMap。
【讨论】:
【参考方案9】:@PostMapping(path = "/my/endpoint", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE )
public ResponseEntity<Void> handleBrowserSubmissions(MyDTO dto) throws Exception
...
这种方式适合我
【讨论】:
这是最简单的答案;在 @RestController 上的 Spring Boot 2.6.0 上为我工作。【参考方案10】:你可以尝试在spring的转换器中开启支持
@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters)
// add converter suport Content-Type: 'application/x-www-form-urlencoded'
converters.stream()
.filter(AllEncompassingFormHttpMessageConverter.class::isInstance)
.map(AllEncompassingFormHttpMessageConverter.class::cast)
.findFirst()
.ifPresent(converter -> converter.addSupportedMediaTypes(MediaType.APPLICATION_FORM_URLENCODED_VALUE));
【讨论】:
【参考方案11】:如果您使用 JMeter 进行测试,只需添加一个 HTTP 标头管理器:
【讨论】:
以上是关于@RequestBody MultiValueMap 不支持内容类型 'application/x-www-form-urlencoded;charset=UTF-8'的主要内容,如果未能解决你的问题,请参考以下文章
@RequestParam @RequestBody @PathVariable 之@requestBody注解的使用
@RequestBody 和 @RequestParam 有啥区别?