Я написал фильтр ответа Java HTTP, в котором я изменяю тело ответа HTTP. Поскольку я меняю тело ответа HTTP, мне нужно обновить заголовок длины содержимого http, отправленный в ответ, в соответствии с новым содержимым. Я делаю это следующим образом.
response.setContentLength( next.getBytes().length );
услышать дальше будет string
Однако этот метод не может установить новую длину содержимого ответа HTTP. Может ли кто-нибудь посоветовать мне, как правильно это сделать в фильтре Java
package com.test;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.CharArrayWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class DumpFilter implements Filter {
private static class ByteArrayServletStream extends ServletOutputStream {
ByteArrayOutputStream baos;
ByteArrayServletStream(ByteArrayOutputStream baos) {
this.baos = baos;
}
public void write(int param) throws IOException {
baos.write(param);
}
}
private static class ByteArrayPrintWriter {
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private PrintWriter pw = new PrintWriter(baos);
private ServletOutputStream sos = new ByteArrayServletStream(baos);
public PrintWriter getWriter() {
return pw;
}
public ServletOutputStream getStream() {
return sos;
}
byte[] toByteArray() {
return baos.toByteArray();
}
}
private class BufferedServletInputStream extends ServletInputStream {
ByteArrayInputStream bais;
public BufferedServletInputStream(ByteArrayInputStream bais) {
this.bais = bais;
}
public int available() {
return bais.available();
}
public int read() {
return bais.read();
}
public int read(byte[] buf, int off, int len) {
return bais.read(buf, off, len);
}
}
private class BufferedRequestWrapper extends HttpServletRequestWrapper {
ByteArrayInputStream bais;
ByteArrayOutputStream baos;
BufferedServletInputStream bsis;
byte[] buffer;
public BufferedRequestWrapper(HttpServletRequest req) throws IOException {
super(req);
InputStream is = req.getInputStream();
baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int letti;
while ((letti = is.read(buf)) > 0) {
baos.write(buf, 0, letti);
}
buffer = baos.toByteArray();
}
public ServletInputStream getInputStream() {
try {
bais = new ByteArrayInputStream(buffer);
bsis = new BufferedServletInputStream(bais);
} catch (Exception ex) {
ex.printStackTrace();
}
return bsis;
}
public byte[] getBuffer() {
return buffer;
}
}
private boolean dumpRequest;
private boolean dumpResponse;
public void init(FilterConfig filterConfig) throws ServletException {
dumpRequest = Boolean.valueOf(filterConfig.getInitParameter("dumpRequest"));
dumpResponse = Boolean.valueOf(filterConfig.getInitParameter("dumpResponse"));
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest httpRequest = (HttpServletRequest)servletRequest;
BufferedRequestWrapper bufferedRequest= new BufferedRequestWrapper(httpRequest);
if (dumpRequest) {
System.out.println("REQUEST -> " + new String(bufferedRequest.getBuffer()));
}
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final ByteArrayPrintWriter pw = new ByteArrayPrintWriter();
HttpServletResponse wrappedResp = new HttpServletResponseWrapper(response) {
public PrintWriter getWriter() {
return pw.getWriter();
}
public ServletOutputStream getOutputStream() {
return pw.getStream();
}
};
filterChain.doFilter(bufferedRequest, wrappedResp);
byte[] bytes = pw.toByteArray();
String s = new String(bytes);
String next = "test message";
response.getOutputStream().write(next.getBytes());
///response.setHeader("Content-Length", String.valueOf(next.length()));
response.setContentLength( next.getBytes().length );
// if (dumpResponse) System.out.println("RESPONSE -> " + s);
}
public void destroy() {}
}
выше приведен класс Filter, но вам может не понадобиться читать весь класс. Ниже приведен код doFilter, в котором я изменяю тело http и устанавливаю длину файла содержимого.
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest httpRequest = (HttpServletRequest)servletRequest;
BufferedRequestWrapper bufferedRequest= new BufferedRequestWrapper(httpRequest);
if (dumpRequest) {
System.out.println("REQUEST -> " + new String(bufferedRequest.getBuffer()));
}
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final ByteArrayPrintWriter pw = new ByteArrayPrintWriter();
HttpServletResponse wrappedResp = new HttpServletResponseWrapper(response) {
public PrintWriter getWriter() {
return pw.getWriter();
}
public ServletOutputStream getOutputStream() {
return pw.getStream();
}
};
filterChain.doFilter(bufferedRequest, wrappedResp);
byte[] bytes = pw.toByteArray();
String s = new String(bytes);
String next = "test message";
response.getOutputStream().write(next.getBytes());
///response.setHeader("Content-Length", String.valueOf(next.length()));
response.setContentLength( next.getBytes().length );
// if (dumpResponse) System.out.println("RESPONSE -> " + s);
}