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

时间:2015-11-19 05:51:01

标签: spring spring-mvc model-view-controller

根据答案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:泽西岛更友好,但现在根据实际限制不能使用它]

11 个答案:

答案 0 :(得分:69)

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

答案 1 :(得分:47)

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

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

答案 2 :(得分:10)

在您的请求中添加标头以将内容类型设置为application / json

curl -H 'Content-Type: application/json' -s -XPOST http://your.domain.com/ -d YOUR_JSON_BODY

这样春天就知道如何解析内容。

答案 3 :(得分:4)

@RequestBody MultiValueMap paramMap

在这里移除@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";
} 

那样

答案 4 :(得分:1)

我在this StackOverflow answer中写过一个替代方案。

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

第一:编写一个对象

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

第三:告诉Spring使用此转换器来实现WebMvcConfigurer.class,该类重写configureMessageConverters方法

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

我正在使用Spring Boot 2。

答案 5 :(得分:0)

在春季5

@PostMapping( "some/request/path" )
public void someControllerMethod( @RequestParam MultiValueMap body ) {

    // import org.springframework.util.MultiValueMap;

    String datax = (String) body .getFirst("datax");
}

答案 6 :(得分:0)

您可以直接使用参数来代替使用地图:

   @RequestMapping(method = RequestMethod.POST, value = "/event/register")
   @ResponseStatus(value = HttpStatus.OK)
   public void registerUser(@RequestParam(name = EVENT_ID) String eventId,
                            @RequestParam(name = ATTENDEE_ID) String attendeeId,
                            @RequestParam(name = SCENARIO) String scenario) {
    log.info("Register user: eventid: {}, attendeeid: {}, scenario: {} ", eventId,attendeeId,scenario);

    //more code here
}

答案 7 :(得分:0)

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

@RestController
public class MyController {

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

答案 8 :(得分:0)

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

那样对我有用

答案 9 :(得分:0)

您可以尝试在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));
    }

}

答案 10 :(得分:0)

如果您正在使用 JMeter 进行测试,只需添加一个 HTTP 标头管理器: enter image description here