Spring MVC - @RequestBody와 @RequestParam을 함께 사용할 수 없는 이유
Post request 및 Content-Type 응용 프로그램/x-www-form-urlencoded에서 HTTP 개발 클라이언트 사용
1) @RequestBody만
URL: localhost:8080/SpringMVC/welcome
본문 : 이름=
@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestBody String body, Model model) {
model.addAttribute("message", body);
return "hello";
}
// Gives body as 'name=abc' as expected
2) @RequestParam만
URL: localhost:8080/SpringMVC/welcome
본문 - name=
@RequestMapping(method = RequestMethod.POST)
public String printWelcome(@RequestParam String name, Model model) {
model.addAttribute("name", name);
return "hello";
}
// Gives name as 'abc' as expected
3) 둘다 같이
URL: localhost:8080/SpringMVC/welcome
본문 : 이름=
@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 Error Code 400 - The request sent by the client was syntactically incorrect.
4) 위에서 매개변수 위치가 변경됨
URL: localhost:8080/SpringMVC/welcome
본문 : 이름=
@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";
}
// No Error. Name is 'abc'. body is empty
5) 함께 있지만 유형 URL 매개 변수 가져오기
URL: localhost:8080/SpringMVC/welcome?name=xyz
본문 : 이름=
@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 is 'xyz' and body is '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' body is empty
누가 이 행동을 설명해 줄 수 있습니까?
그@RequestBody
자바도크 주
메서드 매개 변수를 나타내는 주석은 웹 요청 본문에 바인딩되어야 합니다.
등록된 인스턴스(instance)HttpMessageConverter
요청 본문을 주석이 달린 매개 변수 유형의 개체로 역직렬화합니다.
그리고.@RequestParam
자바도크 주
메서드 매개 변수가 웹 요청 매개 변수에 바인딩되어야 함을 나타내는 주석입니다.
스프링은 요청 본문을 다음과 같이 주석이 달린 매개 변수에 바인딩합니다.
@RequestBody
.Spring은 요청 본문의 요청 매개 변수(url-encoded parameter)를 메서드 매개 변수에 바인딩합니다.Spring은 매개 변수의 이름을 사용합니다. 즉,
name
, 파라미터를 매핑합니다.매개 변수는 순서대로 해결됩니다.
@RequestBody
먼저 처리됩니다.봄은 모든 것을 소비할 것입니다.HttpServletRequest
InputStream
. 그 다음에 그것이 해결하려고 할 때@RequestParam
, 기본적으로required
, 쿼리 문자열에 요청 매개 변수가 없거나 요청 본문에 남아 있는 것, 즉 아무것도 없습니다.따라서 핸들러 방식으로는 요청을 올바르게 처리할 수 없기 때문에 400으로 실패합니다.처리자:
@RequestParam
먼저 행동하고, 그것이 할 수 있는 것을 읽습니다.HttpServletRequest
InputStream
요청 매개 변수, 즉 전체 쿼리 문자열/url-encoded 매개 변수를 매핑합니다.그렇게 해서 가치를 얻게 됩니다.abc
매개 변수에 매핑된name
. 처리자가 다음을 수행할 때@RequestBody
runs, 요청 본문에는 아무것도 남지 않으므로 사용되는 인수는 빈 문자열입니다.처리자:
@RequestBody
본문을 읽고 파라미터에 바인딩합니다.처리자:@RequestParam
그런 다음 URL 쿼리 문자열에서 요청 매개 변수를 가져올 수 있습니다.의 :
@RequestParam
본문과 URL 쿼리 String에서 모두 읽습니다.그것은 보통 그들을 A에 넣곤 했습니다.Map
, 그러나 매개 변수가 유형이기 때문에String
, 봄이 그들을 연재할 것입니다.Map
쉼표로 구분된 값으로.자의 :@RequestBody
그리고 다시, 몸에서 읽을 것이 아무것도 남지 않았습니다.
이 질문에 답하기에는 너무 늦었지만, 새로운 독자들에게 도움이 될 수도 있습니다. 버전 문제인 것 같습니다.스프링 4.1.4로 이 모든 테스트를 실행한 결과,@RequestBody
그리고.@RequestParam
상관없어.
- 자네의 결과와 같은
- 자네의 결과와 같은
- 줬다
body= "name=abc"
,그리고.name = "abc"
- 3과 같습니다.
body ="name=abc"
,name = "xyz,abc"
- 5와 같은
이는 매우 간단한 서블릿 사양 때문에 발생합니다.현지인과 함께 작업하는 경우HttpServletRequest
구현 URL 인코딩 본문과 매개 변수를 둘 다 얻을 수 없습니다.봄은 몇 가지 해결책을 제공하는데, 이것은 봄을 더욱 이상하고 투명하게 만듭니다.
이 경우 Spring(버전 3.2.4)은 데이터를 사용하여 본체를 다시 렌더링합니다.getParameterMap()
방법.GET 파라미터와 POST 파라미터를 혼합하여 파라미터 순서를 바꿉니다.GET 파라미터와 POST 파라미터를 혼합하고 파라미터 순서를 바꿉니다.혼란의 책임이 있는 학급은ServletServerHttpRequest
. 유감스럽게도 그것은 대체할 수 없지만, 클래스는StringHttpMessageConverter
수 있습니다.
깨끗한 해결책은 불행히도 간단하지 않습니다.
-
StringHttpMessageConverter
. 원래 클래스 조정 방법 복사/ 덮어쓰기readInternal()
. -
HttpServletRequest
덮어쓰기getInputStream()
,getReader()
그리고.getParameter*()
방법들.
StringHttpMessageConverter#read 메서드에서내부 다음 코드를 사용해야 합니다.
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 Servlet 요청이 POST 본문에서 한 번 읽은 후에 매개 변수가 손실됨
HTTP 응답 상태 코드 400이 생성되지 않도록 @RequestParam default required status를 false로 변경할 수도 있습니다.이렇게 하면 원하는 순서대로 주석을 배치할 수 있습니다.
@RequestParam(required = false)String name
언급URL : https://stackoverflow.com/questions/19468572/spring-mvc-why-not-able-to-use-requestbody-and-requestparam-together
'programing' 카테고리의 다른 글
개체를 이미 정의된 변수로 구조화하는 방법은 무엇입니까? (0) | 2023.10.19 |
---|---|
때때로 Invalid view state 오류가 발생하면 무시해야 합니까? (0) | 2023.10.19 |
괄호가 있는 경우와 없는 경우의 크기는 언제 사용해야 합니까? (0) | 2023.10.19 |
가상 기능 vs. 기능 포인터 - 성능? (0) | 2023.10.19 |
성능 32비트 대 64비트 산술 (0) | 2023.10.19 |