另一种方法是添加过滤器并使用包装器修改请求/响应对象。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// We need to convert the ServletRequest to MultiReadRequest, so that we could intercept later
MultiReadHttpServletRequest multiReadRequest =
new MultiReadHttpServletRequest((HttpServletRequest) request);
HttpServletResponseWrapper responseWrapper =
new HttpServletResponseWrapper((HttpServletResponse) response);
chain.doFilter(multiReadRequest, responseWrapper);
}
您可以添加代理层(jetty proxy servlet org.eclipse.jetty.proxy.ProxyServlet)并覆盖方法:onResponseContent、addProxyHeaders
public void handleProxyResponse(
HttpServletRequest request,
HttpServletResponse response,
byte[] buffer,
int offset,
int length,
Callback callback) {
try {
if (response.getStatus() == HttpStatus.OK_200
&& request.getRequestURI().startsWith(INTERCEPTED_END_POINT)) {
String output;
boolean acceptsGZipEncoding = acceptsGZipEncoding(request);
if (acceptsGZipEncoding) {
output = plainTextFromGz(buffer);
} else {
output = new String(buffer);
}
String proxyHost = getRequestUrlBase(request);
try {
// TODO: get this from config object
output = output.replace(ProxyServer.REMOTE_HOST, proxyHost);
byte[] outBuffer;
if (acceptsGZipEncoding) {
outBuffer = gzFromPlainText(output);
} else {
outBuffer = output.getBytes();
}
HttpServletResponseWrapper responseWrapper = (HttpServletResponseWrapper) response;
responseWrapper.getResponse().reset();
responseWrapper.getOutputStream().write(outBuffer);
} catch (Exception e) {
log.error(e.getMessage(), e);
// Error in parsing json, writing original response
response.getOutputStream().write(buffer, offset, length);
}
} else {
response.getOutputStream().write(buffer, offset, length);
}
callback.succeeded();
} catch (Throwable e) {
callback.failed(e);
}
}
private String getRequestUrlBase(HttpServletRequest request) {
logHeaders(request);
return request.getHeader(HttpHeader.HOST.name());
}
private String replaceBaseFromUrl(String url, String base) throws Exception {
URI uri = new URI(url);
StringBuffer sb = new StringBuffer("");
if (base.startsWith("http")) {
sb.append(base);
} else {
sb.append("http://").append(base);
}
sb.append(uri.getPath());
if (!Strings.isNullOrEmpty(uri.getQuery())) {
sb.append("?").append(uri.getQuery());
}
return sb.toString();
}
private boolean acceptsGZipEncoding(HttpServletRequest httpRequest) {
String acceptEncoding = httpRequest.getHeader("Accept-Encoding");
return acceptEncoding != null && acceptEncoding.indexOf("gzip") != -1;
}
private byte[] gzFromPlainText(String plainText) {
if (Strings.isNullOrEmpty(plainText)) {
return null;
}
try (final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final GZIPOutputStream gzipOutput = new GZIPOutputStream(baos)) {
gzipOutput.write(plainText.getBytes());
gzipOutput.finish();
return baos.toByteArray();
} catch (IOException e) {
log.error("Could not convert plain text to gz", e);
}
return plainText.getBytes();
}
private String plainTextFromGz(byte[] gz) {
try (GZIPInputStream gzipIn = new GZIPInputStream(new ByteArrayInputStream(gz))) {
return IOUtils.toString(gzipIn, Charset.defaultCharset());
} catch (IOException e) {
log.error("Could not write gz to plain text", e);
}
return new String(gz);
}