Answer the question
In order to leave comments, you need to log in
How to get response body size in Java Servlet Filter?
How can I find out the size of the response (bytes) after passing through the filters chain?
Filter code:
@WebFilter(urlPatterns={"/*"})
public class MyFilter implements Filter {
private final Logger logger = Logger.getLogger(getClass().getSimpleName());
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
filterChain.doFilter(servletRequest, servletResponse);
// httpResponse.getContentLength() ???
}
@Override
public void destroy() {}
}
Answer the question
In order to leave comments, you need to log in
Одно из возможных решений заключается в следующем.
- подменяем в цепочке фильтров (filterChain.doFilter(...)) объект response на кастомный, который умеет фиксировать контент и позволяет получать содержимое буфера;
- после filterChain.doFilter(...) с подменённым респонсом используем реализованные для него методы и получаем контент, а уже из контента легко считаем contentLength;
Код.
public class ContentCaptureResponse extends HttpServletResponseWrapper {
private ByteArrayOutputStream contentBuffer;
private PrintWriter writer;
public ContentCaptureResponse(HttpServletResponse response) {
super(response);
}
@Override
public PrintWriter getWriter() throws IOException {
if (writer == null) {
writer = new PrintWriter(getContentBuffer());
}
return writer;
}
private ByteArrayOutputStream getContentBuffer() {
if (contentBuffer == null) {
contentBuffer = new ByteArrayOutputStream();
}
return contentBuffer;
}
public String getContent() throws IOException {
getWriter().flush();
return new String(getContentBuffer().toString());
}
}
@WebFilter(urlPatterns={"/*"})
public class RequestTrack implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
ContentCaptureResponse contentCaptureResponse = new ContentCaptureResponse(httpResponse);
filterChain.doFilter(servletRequest, contentCaptureResponse);
String content = contentCaptureResponse.getContent();
// content.length();
// оригинальный response у нас будет пуст, так как в doFilter() мы подменили объект, поэтому пишем в outputStream оригинального response контент, который получили в ответе
servletResponse.getOutputStream().write(content.getBytes(StandardCharsets.UTF_8));
}
@Override
public void destroy() {}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question