복붙노트

[SPRING] 스프링 MVC - @RequestBody와 @RequestParam을 함께 사용할 수없는 이유

SPRING

스프링 MVC - @RequestBody와 @RequestParam을 함께 사용할 수없는 이유

POST 요청 및 Content-Type 응용 프로그램 / x-www-form-urlencoded와 함께 HTTP dev 클라이언트 사용

1) @RequestBody 만

요청 - localhost : 8080 / SpringMVC / welcome 본문 - 이름 = abc 있음

암호-

@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestBody String body, Model model) {
    model.addAttribute("message", body);
    return "hello";
}

// 예상대로 body를 'name = abc'로 지정합니다.

2) @RequestParam 만

요청 - localhost : 8080 / SpringMVC / welcome 본문 - 이름 = abc 있음

암호-

@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestParam String name, Model model) {
    model.addAttribute("name", name);
    return "hello";
}

// 예상대로 이름을 'abc'로 지정합니다.

3) 함께

요청 - localhost : 8080 / SpringMVC / welcome 본문 - 이름 = abc 있음

암호-

@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestBody String body, @RequestParam String name, Model model) {
    model.addAttribute("name", name);
    model.addAttribute("message", body);
    return "hello";
}

// HTTP 오류 코드 400 - 클라이언트가 보낸 요청의 구문이 올바르지 않습니다.

4) 위의 매개 변수 위치가 변경됨

요청 - localhost : 8080 / SpringMVC / welcome 본문 - 이름 = abc 있음

암호-

@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestParam String name, @RequestBody String body, Model model) {
    model.addAttribute("name", name);
    model.addAttribute("message", body);
    return "hello";
}

// 오류 없음. 이름은 'abc'입니다. 시체가 비어있다.

5) 함께하지만 형식 URL 매개 변수를 가져옵니다.

요청 - localhost : 8080 / SpringMVC / welcome? name = xyz 본문 - 이름 = abc 있음

암호-

@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestBody String body, @RequestParam String name, Model model) {
    model.addAttribute("name", name);
    model.addAttribute("message", body);
    return "hello";
}

// name은 'xyz'이고 body는 'name = abc'입니다.

6) 5)와 동일하지만 매개 변수 위치가 변경됨

코드 -

@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestParam String name, @RequestBody String body, Model model) {
    model.addAttribute("name", name);
    model.addAttribute("message", body);
    return "hello";
}

// name = 'xyz, abc'본문이 비어 있습니다.

누군가이 행동을 설명 할 수 있습니까?

해결법

  1. ==============================

    1.@RequestBody javadoc 상태

    @RequestBody javadoc 상태

    HttpMessageConverter의 등록 된 인스턴스를 사용하여 요청 본문을 주석 된 매개 변수 유형의 개체로 deserialize합니다.

    그리고 @RequestParam

  2. ==============================

    2.나는이 질문에 대답하기에는 너무 늦었다 고 알고 있지만, 여전히 독자들에게 도움이 될 수 있습니다. 그것은 버전 문제가 보인다. 나는 봄 4.1.4로이 모든 테스트를 실행하고 @RequestBody와 @RequestParam의 순서가 중요하지 않음을 발견했다.

    나는이 질문에 대답하기에는 너무 늦었다 고 알고 있지만, 여전히 독자들에게 도움이 될 수 있습니다. 그것은 버전 문제가 보인다. 나는 봄 4.1.4로이 모든 테스트를 실행하고 @RequestBody와 @RequestParam의 순서가 중요하지 않음을 발견했다.

  3. ==============================

    3.HTTP 응답 상태 코드 400이 생성되지 않도록 @RequestParam 기본 필수 상태를 false로 변경할 수도 있습니다. 이렇게하면 Annotations를 원하는 순서대로 배치 할 수 있습니다.

    HTTP 응답 상태 코드 400이 생성되지 않도록 @RequestParam 기본 필수 상태를 false로 변경할 수도 있습니다. 이렇게하면 Annotations를 원하는 순서대로 배치 할 수 있습니다.

    @RequestParam(required = false)String name
    
  4. ==============================

    4.그것은 매우 똑바로 서블릿 사양 때문에 발생합니다. 기본 HttpServletRequest 구현으로 작업하는 경우 URL 인코딩 본문과 매개 변수를 모두 가져올 수 없습니다. Spring은 좀 더 이상하고 불투명 한 몇 가지 해결 방법을 제공합니다.

    그것은 매우 똑바로 서블릿 사양 때문에 발생합니다. 기본 HttpServletRequest 구현으로 작업하는 경우 URL 인코딩 본문과 매개 변수를 모두 가져올 수 없습니다. Spring은 좀 더 이상하고 불투명 한 몇 가지 해결 방법을 제공합니다.

    그런 경우 Spring (버전 3.2.4)은 getParameterMap () 메소드의 데이터를 사용하여 본문을 다시 렌더링합니다. GET 및 POST 매개 변수를 혼합하여 매개 변수 순서를 나눕니다. 혼돈을 초래하는 클래스는 ServletServerHttpRequest입니다. 불행히도 대체 할 수는 없지만 StringHttpMessageConverter 클래스가 될 수 있습니다.

    깨끗한 솔루션은 불행히도 간단하지 않습니다.

    StringHttpMessageConverter 메서드에서 # readInternal 다음 코드를 사용해야합니다.

        if (inputMessage instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest oo = (ServletServerHttpRequest)inputMessage;
            input = oo.getServletRequest().getInputStream();
        } else {
            input = inputMessage.getBody();
        }
    

    그런 다음 변환기를 컨텍스트에 등록해야합니다.

    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true/false">
            <bean class="my-new-converter-class"/>
       </mvc:message-converters>
    </mvc:annotation-driven>
    

    2 단계는 여기에 설명되어 있습니다 : Http 서블릿 요청은 한번 읽은 후에 POST 본문에서 매개 변수를 잃습니다.

  5. from https://stackoverflow.com/questions/19468572/spring-mvc-why-not-able-to-use-requestbody-and-requestparam-together by cc-by-sa and MIT license