@RequestBody MultiValueMap不支持内容类型'application / x-www-form-urlencoded; charset = UTF-8'


95

基于Spring @Controller的x-www-form-urlencoded问题的答案

我写了下面的@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:泽西岛要友好得多,但鉴于这里的实际限制,现在无法使用它]


您是否在@RequestBody中添加了消耗= {“ application / x-www-form-urlencoded”}?
shiladitya 2015年

1
您是如何执行请求的?添加代码(js,jquery,curl或您使用的任何代码)。
Nikolay Rusev 2015年

我也有同样的问题。就我而言,我使用jquery ajax发布数据,数据为JSON.stringify({"ordersToDownload":"00417002"}
Arashsoft

这是我使用的代码:$.ajax({url:"/myurl", type:"POST", data: JSON.stringify({"someAttribute":"someData"}) })
Arashsoft

Answers:


126

问题在于,当我们使用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

回答内容类型为application / x-www-form-urlencoded的Http Post请求在Spring中不起作用


谢谢!解决问题。现在,我想知道如何显式删除 application/x-www-form-urlencoded
kholofelo Maloma

1
没必要@kholofeloMaloma
Douglas Ribeiro

如果有人想知道为什么这没有注释就行得通,似乎Spring会处理任何未注释的参数,就好像它们具有@ModelAttribute, even though this behaviour is (sadly) not documented. And @ModelAttribute确实理解了x-www-form-urlencoded
cranphin

公共ResponseEntity <?> getToken(MultiValueMap paramMap)IllegalArgumentException:参数类型不匹配
存在

谢谢(你的)信息!作为一个新手,我想知道Spring解析负载并将其绑定到对象的这种奇怪行为的背后原因是什么?
hafan96

66

看来现在您可以只用标记方法参数,@RequestParam它将为您完成工作。

@PostMapping( "some/request/path" )
public void someControllerMethod( @RequestParam Map<String, String> body ) {
  //work with Map
}

18

向您的请求添加标头以将内容类型设置为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”'等
。– razvanone

1
您能否解释一下如何将此设置添加到我的HTML表单中?
Osama Al-Banna

8

春季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时,先生,您应该获得更多积分!谢谢!现在需要@RequestParam接缝才能从请求中提取MultiValueMap
NemanjaT

2

只需删除@RequestBody注释即可解决问题(在Spring Boot 2上测试):

@RestController
public class MyController {

    @PostMapping
    public void method(@Valid RequestDto dto) {
       // method body ...
    }
}

1

我在这个StackOverflow答案中写了一个替代方法。

我在那里逐步编写代码并进行解释。简短的方法:

首先:写一个对象

第二:创建一个转换器以映射扩展AbstractHttpMessageConverter的模型

第三:告诉Spring使用此转换器来实现一个重写configureMessageConverters方法的WebMvcConfigurer.class

第四个也是最后一个:在控制器内部的映射中使用此实现设置,在对象前面消耗= MediaType.APPLICATION_FORM_URLENCODED_VALUE和@RequestBody。

我正在使用Spring Boot 2。


0
@PostMapping(path = "/my/endpoint", consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE })
public ResponseEntity<Void> handleBrowserSubmissions(MyDTO dto) throws Exception {
    ...
}

这样对我有用

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.