[SPRING] Spring 'HandlerMethodArgumentResolver'에서 요청 본문을 여러 번 읽으려면 어떻게해야합니까?
SPRINGSpring 'HandlerMethodArgumentResolver'에서 요청 본문을 여러 번 읽으려면 어떻게해야합니까?
요청 본문에서 값을 추출하고 유효성을 검사하여 특정 주석 매개 변수에 주입하기 위해 RequestMapping 메서드의 일부 매개 변수를 해결하려고합니다.
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
// 1, get corresponding input parameter from NativeWebRequest
// 2, validate
// 3, type convertion and assemble value to return
return null;
}
가장 큰 문제는 HttpServletRequest (NativeWebRequest에서 가져 오기)가 한 번 이상 입력 스트림 (일부 매개 변수가 요청 본문에 있음)을 읽을 수 없다는 것입니다. 그렇다면 Inputstream / Reader 또는 요청 본문을 두 번 이상 검색하려면 어떻게해야합니까?
해결법
-
==============================
1.필터를 추가하고 현재 HttpServletRequest를 가로 채서 사용자 정의 HttpServletRequestWrapper로 래핑 할 수 있습니다. 사용자 정의 HttpServletRequestWrapper에서 요청 본문을 읽고 캐시 한 다음 getInputStream 및 getReader를 구현하여 캐시 된 값을 읽습니다. 요청을 래핑 한 후 캐시 된 값이 항상 존재하므로 요청 본문을 여러 번 읽을 수 있습니다.
필터를 추가하고 현재 HttpServletRequest를 가로 채서 사용자 정의 HttpServletRequestWrapper로 래핑 할 수 있습니다. 사용자 정의 HttpServletRequestWrapper에서 요청 본문을 읽고 캐시 한 다음 getInputStream 및 getReader를 구현하여 캐시 된 값을 읽습니다. 요청을 래핑 한 후 캐시 된 값이 항상 존재하므로 요청 본문을 여러 번 읽을 수 있습니다.
@Component public class CachingRequestBodyFilter extends GenericFilterBean { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest currentRequest = (HttpServletRequest) servletRequest; MultipleReadHttpRequest wrappedRequest = new MultipleReadHttpRequest(currentRequest); chain.doFilter(wrappedRequest, servletResponse); } }
이 필터 후에는 여러 번 읽을 수있는 wrappedRequest가 모두에게 표시됩니다.
public class MultipleReadHttpRequest extends HttpServletRequestWrapper { private ByteArrayOutputStream cachedContent; public MultipleReadHttpRequest(HttpServletRequest request) throws IOException { // Read the request body and populate the cachedContent } @Override public ServletInputStream getInputStream() throws IOException { // Create input stream from cachedContent // and return it } @Override public BufferedReader getReader() throws IOException { // Create a reader from cachedContent // and return it } }
MultipleReadHttpRequest를 구현하기 위해 기본적으로 동일한 작업을 수행하는 Spring 프레임 워크에서 ContentCachingRequestWrapper를 살펴볼 수 있습니다.
이 접근법에는 자체 단점이 있습니다. 우선, 모든 요청에 대해 요청 본문이 적어도 두 번 읽혀지기 때문에 다소 비효율적입니다. 다른 중요한 단점은 요청 본문에 10GB 상당의 스트림이 포함되어 있고 10GB의 데이터를 읽었을 때 더 심해질 수 있으므로 더 많은 검토를 위해이를 메모리로 가져와야한다는 것입니다.
from https://stackoverflow.com/questions/34804205/how-can-i-read-request-body-multiple-times-in-spring-handlermethodargumentresol by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 어노테이션을 사용하여 빈 생성자에 값을 주입하는 방법 (0) | 2018.12.25 |
---|---|
[SPRING] 봄 부팅 응용 프로그램에서 봄 보안 해제 (0) | 2018.12.25 |
[SPRING] MyBatis / Spring을 사용하여 배치 작업을 구현하는 방법은 무엇입니까? (0) | 2018.12.25 |
[SPRING] 구성 클래스에 대한 가져 오기 후보를 처리하지 못했습니다. (0) | 2018.12.25 |
[SPRING] 스프링 배치에서 멀티 스레딩을 설정하는 방법은 무엇입니까? (0) | 2018.12.25 |