У меня есть собственный фильтр, который манипулирует ответом. Каркас фильтра выглядит следующим образом.
Оболочка ответа,
public class CustomResponseWrapper extends HttpServletResponseWrapper {
private final ByteArrayOutputStream capture;
private ServletOutputStream output;
private PrintWriter writer;
public CustomResponseWrapper(HttpServletResponse response) {
super(response);
capture = new ByteArrayOutputStream(response.getBufferSize());
}
@Override
public ServletOutputStream getOutputStream() {
if (writer != null) {
throw new IllegalStateException("getWriter() has already been called on this response");
}
if (output == null) {
// To manipulate the response
output = new ServletOutputStream() {
@Override
public void write(int b) throws IOException {
capture.write(b);
}
@Override
public void flush() throws IOException {
capture.flush();
}
@Override
public void close() throws IOException {
capture.close();
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener arg0) {
}
};
}
return output;
}
@Override
public PrintWriter getWriter() throws IOException {
if (output != null) {
throw new IllegalStateException("getOutputStream() has already been called on this response.");
}
if (writer == null) {
writer = new PrintWriter(new OutputStreamWriter(capture,
getCharacterEncoding()));
}
return writer;
}
@Override
public void flushBuffer() throws IOException {
super.flushBuffer();
if (writer != null) {
writer.flush();
} else if (output != null) {
output.flush();
}
}
@Override
public void setCharacterEncoding(String charset) {
super.setCharacterEncoding(charset);
}
public byte[] getCaptureAsBytes() throws IOException {
if (writer != null) {
writer.close();
} else if (output != null) {
output.close();
}
return capture.toByteArray();
}
public String getCaptureAsString() throws IOException {
return new String(getCaptureAsBytes(), getCharacterEncoding());
}
}
Фильтр,
public class CustomInjectFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
PrintWriter originalOut = servletResponse.getWriter();
CustomResponseWrapper responseWrapper = new CustomResponseWrapper((HttpServletResponse) servletResponse);
filterChain.doFilter(servletRequest, responseWrapper);
String originalContent = responseWrapper.getCaptureAsString();
// Do the changes i need to do here
String jsonData = "....";
servletResponse.setCharacterEncoding("...");
servletResponse.setContentType("...");
servletResponse.setContentLength(jsonData.lenth());
originalOut.write(jsonData);
originalOut.flush();
originalOut.close();
}
}
setContentLength
здесь не имеет никакого эффекта, а вместо этого длина ответапоказывает исходную длину каждый раз.
Есть ли причина, по которой setContentLength и методы set на ответ не влияют в этом случае?