복붙노트

[SPRING] @RequestBody가 여러 개있는 스프링 MVC 컨트롤러

SPRING

@RequestBody가 여러 개있는 스프링 MVC 컨트롤러

예를 들어 SpringMVC 컨트롤러가 다음과 같은 메서드 서명을 가질 수 있는지 궁금합니다.

@RequestMapping(value = "/target", method = RequestMethod.POST)
@ResponseBody
public void acceptObject(@RequestBody MyObjectDto dto,@RequestBody String messageBody) {
    //Authenticate messageBody
    //Process mapped DTO
}

의도는 JSON이이 컨트롤러에 게시되고 원시 메시지 본문이 무결성을 위해 인증되며 올바른 경우 처리를 위해 전달 될 수있는 DTO에 JSON이 매핑된다는 것입니다.

순간에 나는 결국

java.io.IOException: Stream closed

해결법

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

    1.Spring은 HandlerMethodArgumentResolver라는 인터페이스를 사용하여 핸들러 메소드에 전달할 인수를 결정합니다. @RequestBody로 주석 된 매개 변수의 경우 RequestResponseBodyMethodProcessor라는 클래스를 사용합니다. 이 클래스는 기본적으로 요청의 content-type을 읽을 수 있고 지정된 유형으로 변환 할 수있는 HttpMessageConverter 객체 집합을 찾습니다. 하나를 찾으면 HttpServletRequest 본문을 InputStream으로 HttpMessageConverter 개체에 전달합니다.

    Spring은 HandlerMethodArgumentResolver라는 인터페이스를 사용하여 핸들러 메소드에 전달할 인수를 결정합니다. @RequestBody로 주석 된 매개 변수의 경우 RequestResponseBodyMethodProcessor라는 클래스를 사용합니다. 이 클래스는 기본적으로 요청의 content-type을 읽을 수 있고 지정된 유형으로 변환 할 수있는 HttpMessageConverter 객체 집합을 찾습니다. 하나를 찾으면 HttpServletRequest 본문을 InputStream으로 HttpMessageConverter 개체에 전달합니다.

    이 경우에는 JSON 디시리얼라이저가 작동하는 것을 볼 수있을 것입니다. 스트림 (stream)을 소비 한 다음 닫는 것이 매우 가능성이 높습니다 (IOException을 보게 될 것입니다).

    이렇게 진짜로 일을하는이 방법은 직접 가능하지 않습니다.

    한가지 해결책은 HttpServletRequest를 자신의 구현에 랩핑하는 필터를 만들어서 필요한만큼 여러 번 재사용 / 재사용 할 수 있도록 InputStream을 버퍼링하는 것입니다. 그러나 다시 시체에서 비 직렬화에 대한 규칙은 스프링에 의해 가정 될 수 있으며 정확하게 원하는 것은 아닙니다. 이 경우 자신 만의 Annotation과 HandlerMethodArgumentResolver를 생성 할 수 있습니다. 그런 다음 구성에 응용 프로그램에 등록합니다. 그런 다음 요청 본문에서 항목이 deserialize되는 방식을 정확하게 제어 할 수 있습니다.

    또 다른 해결책은 MyObjectDto와 messageBody를 하나의 DTO로 결합하는 것입니다 (데이터 모델과 Spring 비 직렬화 프로세스에 의미가있는 경우).

  2. from https://stackoverflow.com/questions/18690736/spring-mvc-controller-with-multiple-requestbody by cc-by-sa and MIT license