Одно из возможных решений заключается в следующем.
- подменяем в цепочке фильтров (
filterChain.doFilter(...)) объект response на кастомный, который умеет фиксировать контент и позволяет получать содержимое буфера;
- после
filterChain.doFilter(...) с подменённым респонсом используем реализованные для него методы и получаем контент, а уже из контента легко считаем contentLength;
Код.
ContentCaptureResponse.classpublic 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());
}
}
Фильтр, RequestTrack.class@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() {}
}