Filter处理HttpServletRequest & HttpServletResponse 笔记

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);
            }
        }


猜你喜欢

转载自blog.csdn.net/boneix/article/details/78754510