HttpServletRequest - InputStream 여러번 읽기

sarah·2023년 3월 28일
0

https://velog.io/@dayoung_sarah/content-type%EB%B3%84-request-body-%EC%9D%BD%EA%B8%B0

위 글을 작성하고, InputStream 을 두번 읽는 상황이 바로 나에게 발생하였다....

나의 상황은 Filter에서 InputStream을 먼저 읽고 있었고, AOP 에서 request body를 읽기위해서 InputStream을 다시 사용하고 있어서 읽히지 않았다.

구글링 해본 결과, HttpServletRequestWrapper 클래스를 사용하여 InputStream을 복사해두고, filter에서 wrapper 클래스를 넘겨주라는 것이였다.

아래는 적용한 코드이다.

public class TestFilter implements Filter {
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
		HttpRequestWrapper httpRequestWrapper = new HttpRequestWrapper((HttpServletRequest) servletRequest);
		// servletRequest 에서 InputStream 꺼내와서 사용
		filterChain.doFilter(httpRequestWrapper, response);
	}
}
public class HttpRequestWrapper extends HttpServletRequestWrapper {
	private byte[] bodyData;

	public HttpRequestWrapper(HttpServletRequest request) throws IOException {
		super(request);
		InputStream is = super.getInputStream();
		bodyData = IOUtils.toByteArray(is);
	}
	@Override
	public ServletInputStream getInputStream() throws IOException {
		final ByteArrayInputStream bis = new ByteArrayInputStream(bodyData);
		return new ServletImpl(bis);
	}
}

class ServletImpl extends ServletInputStream {
	private InputStream is;

	public ServletImpl(InputStream bis) {
		is = bis;
	}

	@Override
	public int read() throws IOException {
		return is.read();
	}

	@Override
	public int read(byte[] b) throws IOException {
		return is.read(b);
	}

	@Override
	public boolean isFinished() {
		return false;
	}

	@Override
	public boolean isReady() {
		return false;
	}

	@Override
	public void setReadListener(ReadListener readListener) {

	}
}

[참고]
https://groups.google.com/g/ksug/c/LyFiv-2TlBo

0개의 댓글