@RequestBody MultiValueMap에 대해 콘텐츠 유형 'application / x-www-form-urlencoded; charset = UTF-8'이 지원되지 않습니다.


94

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"
}

[추신 : Jersey는 훨씬 더 친근했지만 여기서는 실제적인 제한을 감안할 때 사용할 수 없었습니다.]


@RequestBody에 소비 = { "application / x-www-form-urlencoded"}를 추가 했습니까?
shiladitya

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

내 대답을 확인하십시오 여기에 링크 설명
Eshiett Oto-obong

답변:


125

문제는 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가 Spring에서 작동하지 않는 Http Post 요청


감사합니다! 문제를 해결합니다. 이제 어떻게 명시 적으로 application/x-www-form-urlencoded?
kholofelo Maloma

1
그것은 필요 @kholofeloMaloma하지 않습니다
더글러스 리베

왜 이것이 주석없이 작동하는지 궁금한 사람이 있다면 Spring은 @ModelAttribute, even though this behaviour is (sadly) not documented. And @ModelAttribute가 x-www-form-urlencoded를 이해 하는 것처럼 주석이없는 인수를 처리하는 것 같습니다.
cranphin

public ResponseEntity <?> getToken (MultiValueMap paramMap) IllegalArgumentException : 인수 유형 불일치
withoutOne

정보에 대해서 감사드립니다! 초보자로서 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를 매핑에 포함 시키면 더 많은 포인트를받을 자격이 있습니다! 감사합니다! 요청에서 MultiValueMap을 선택하려면 @RequestParam 이음새가 필요합니다.
NemanjaT

2

단순히 @RequestBody주석을 제거 하면 문제가 해결됩니다 (Spring Boot 2에서 테스트 됨).

@RestController
public class MyController {

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

1

이 StackOverflow 답변 에서 대안에 대해 썼습니다 .

거기에 코드로 설명하면서 단계별로 작성했습니다. 짧은 방법 :

첫째 : 개체 작성

두 번째 : AbstractHttpMessageConverter를 확장하는 모델 매핑을위한 변환기 생성

셋째 : configureMessageConverters 메서드를 재정의하는 WebMvcConfigurer.class를 구현하는이 변환기를 사용하도록 봄에 알립니다.

네 번째 이자 마지막 : 컨트롤러 내부의 매핑에서이 구현 설정을 사용하면 개체 앞에서 = MediaType.APPLICATION_FORM_URLENCODED_VALUE 및 @RequestBody를 사용합니다.

스프링 부트 2를 사용하고 있습니다.


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

그 방법은 나를 위해 작동합니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.