HttpServletRequest 及HttpServletResponse 的复制 通过BufferedServletRequestWrapper和ContentCachingResponseWrapper进行处理
import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; /** * Created by ylzhou on 2017/6/22. */ public class BufferedServletRequestWrapper extends HttpServletRequestWrapper { private byte[] buffer; public BufferedServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); InputStream is = request.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte buff[] = new byte[1024]; int read; while ((read = is.read(buff)) > 0) { baos.write(buff, 0, read); } this.buffer = baos.toByteArray(); } @Override public ServletInputStream getInputStream() throws IOException { return new BufferedServletInputStream(this.buffer); } }
import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; /** * Created by ylzhou on 2017/6/22. */ public class BufferedServletInputStream extends ServletInputStream { private ByteArrayInputStream inputStream; public BufferedServletInputStream(byte[] buffer) { this.inputStream = new ByteArrayInputStream(buffer); } @Override public int read(byte[] b, int off, int len) throws IOException { return inputStream.read(b, off, len); } @Override public int available() throws IOException { return inputStream.available(); } @Override public int read() throws IOException { return inputStream.read(); } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener listener) { } }需要注意的是复制出的HttpServletRequest 需要关闭,而复制出的HttpServletResponse 需要回写结果
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { if (!(servletRequest instanceof HttpServletRequest) || !(servletResponse instanceof HttpServletResponse)) { throw new ServletException("Filter just supports HTTP requests"); } // 复制request HttpServletRequest bufferedWrapper = new BufferedServletRequestWrapper((HttpServletRequest) servletRequest); // 切入 ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(bufferedWrapper); ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) servletResponse); // 截取request值 HttpHeaders requestHeaders = new HttpHeaders(); Enumeration headerNames = requestWrapper.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = (String) headerNames.nextElement(); requestHeaders.add(headerName, requestWrapper.getHeader(headerName)); } Map<String, String[]> requestParams = requestWrapper.getParameterMap(); String requestBody = ""; InputStream inputStream = null; try { inputStream = requestWrapper.getInputStream(); requestBody = IOUtils.toString(requestWrapper.getInputStream(), StandardCharsets.UTF_8); } catch (IOException e) { logger.error("获取请求body失败{}", e); } finally { // 由于inputStream是复制出来的,所以需要关闭 IOUtils.closeQuietly(inputStream); } try { new SpanExtraInfo .SpanExtraInfoBuild() .requestHeaders(JSONUtils.toJson(requestHeaders)) .requestParams(JSONUtils.toJson(requestParams)) .requestBody(requestBody) .build(); } catch (JsonProcessingException exc) { log.warn("request info analyze error! {}", exc); } // 调用父,这里的需传入bufferedWrapper super.doFilter(bufferedWrapper, responseWrapper, filterChain); }
SpanExtraInfo spanExtraInfo = SpanExtraInfo.getInstance(); tracer.addTag("requestHeaders", spanExtraInfo.getRequestHeaders()); tracer.addTag("requestParams", spanExtraInfo.getRequestParams()); tracer.addTag("requestBody", spanExtraInfo.getRequestBody()); if (response instanceof ContentCachingResponseWrapper) { ContentCachingResponseWrapper responseWrapper = (ContentCachingResponseWrapper) response; HttpHeaders responseHeaders = new HttpHeaders(); for (String headerName : responseWrapper.getHeaderNames()) { responseHeaders.add(headerName, responseWrapper.getHeader(headerName)); } try { tracer.addTag("responseHeaders", JSONUtils.toJson(responseHeaders)); } catch (JsonProcessingException exc) { log.warn("responseHeaders analyze error! {}", exc); } try { String responseBody = IOUtils.toString(responseWrapper.getContentInputStream(), StandardCharsets.UTF_8); tracer.addTag("responseBody", responseBody); // 最后需要回写下servletResponse,否则会返回一个空的servletResponse responseWrapper.copyBodyToResponse(); } catch (IOException exc) { log.warn("responseBody analyze error! {}", exc); } }