2015년 5월 31일 일요일

spring http request body 복사 방법



Interceptor를 이용해서는 불가능하고 filter를 이용하여 복사하여 로깅이 가능하다. 
HttpServletRequestWrapper 클래스를 이용하여 해당 inputsrtream에 대해서 복사를  통하여 새로운 inputstream를 생성해서 전달하는 방법으로 구현이 가능하다.

 - inputstream을 전달 받은 그대로 사용하게 되면 해당 Inputstream의 커서의 이동으로 해당 inpuststream의 재사용이 불가능하여 controller에서 사용시 에러가 발생한다.


하지만 interceptor의 경우 HttpServletRequest를 새로운 Request로 주입이 불가능하여 구현이 불가능한 것으로 보여진다. 

아래의 코드 참고 (reqest에 대해서 로깅하는 클래스 구현)


@Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpRequestWrapper requestWrapper = new HttpRequestWrapper(request);

        log.debug("======================================          REQUEST         ======================================{}" );
        Enumeration<String> requestHeaderNames = requestWrapper.getHeaderNames();
        while (requestHeaderNames.hasMoreElements()) {
            String headerName = requestHeaderNames.nextElement();
            Enumeration<String> headers = requestWrapper.getHeaders(headerName);
            while (headers.hasMoreElements()) {
                String headerValue = headers.nextElement();
                log.debug(" Request HEADER - {} : {} ", headerName, headerValue );
            }
            
        }
        log.debug(" Request METHOD:{} URI:{}  ", requestWrapper.getMethod(), requestWrapper.getRequestURI());
        if(requestWrapper.getMethod().equalsIgnoreCase("POST")||requestWrapper.getMethod().equalsIgnoreCase("PUT")){
            log.debug(" Request Body:  {}", StringHelper.getString(requestWrapper.getInputStream()));
        }
        
        chain.doFilter(requestWrapper, response);
    }
===============================

public class HttpRequestWrapper extends HttpServletRequestWrapper {

/** HTTP request body data */
private byte[] bodyData;

/**
 * @param request
 * @throws IOException
 */
public HttpRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
InputStream is = super.getInputStream();
bodyData = IOUtils.toByteArray(is);
}

/**
 * <pre>
 * getInputStream
 *
 * <pre>
 * @return
 * @throws IOException
 */
@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);
}

}

댓글 없음:

댓글 쓰기