Use a custom Filter class to filter tomcat server HTTP requests and replies

Principle: Customize the filter class, inherit javax.servlet.Filter, and implement filtering of HTTP requests and replies in the doFilter interface

1. LogFilter: implement filtering function

package com.test.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.InetAddress;
import java.util.Calendar;

@WebFilter(urlPatterns = "/*")
public class LogFilter implements Filter {

    @Override
    public void init(FilterConfig fConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if((servletRequest instanceof HttpServletRequest) == false) {
            System.out.println();
            filterChain.doFilter(servletRequest, servletResponse);
        }
        else
        {
            int y, m, d, h, min, s;
            Calendar cal=Calendar.getInstance();
            y=cal.get(Calendar.YEAR);
            m=cal.get(Calendar.MONTH);
            d=cal.get(Calendar.DATE);
            h=cal.get(Calendar.HOUR_OF_DAY);
            min=cal.get(Calendar.MINUTE);
            s=cal.get(Calendar.SECOND);
            java.lang.String outputStr = String.format(
                    "\n[%04d-02%d-%02d %02d:%02d:%02d] LogFilter Front\n", y, m, d, h, min, s);
            System.out.println(outputStr);

            FilterHttpServletRequest filterReq =
                    new FilterHttpServletRequest((HttpServletRequest)servletRequest);

            System.out.println(filterReq.getRemoteHost());
            System.out.println(filterReq.getContextPath());
            System.out.println(filterReq.getRequestURL());
            System.out.println(filterReq.getRequestURI());
            System.out.println(filterReq.getQueryString());

            BufferedReader br;
            try {
                br = filterReq.getReader();
                String str, wholeParams = "";
                while((str = br.readLine()) != null){
                    wholeParams += str;
                }
                System.out.println(wholeParams);
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println();

            FilterHttpServletResponse filterResp =
                    new FilterHttpServletResponse((HttpServletResponse)servletResponse);
            filterChain.doFilter(filterReq, filterResp);

            cal=Calendar.getInstance();
            y=cal.get(Calendar.YEAR);
            m=cal.get(Calendar.MONTH);
            d=cal.get(Calendar.DATE);
            h=cal.get(Calendar.HOUR_OF_DAY);
            min=cal.get(Calendar.MINUTE);
            s=cal.get(Calendar.SECOND);
            outputStr = String.format(
                    "\n[%04d-02%d-%02d %02d:%02d:%02d] LogFilter Post\n", y, m, d, h, min, s);
            System.out.println(outputStr);

            System.out.println(filterResp.getResponseBody());
            System.out.println();
        }
    }
}

2. FilterHttpServletRequest: wrap HTTP request

package com.test.filter;

import org.springframework.util.StreamUtils;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;

public class FilterHttpServletRequest extends HttpServletRequestWrapper {

    private byte[] cachedBody;

    public FilterHttpServletRequest(HttpServletRequest request) throws IOException {
        super(request);
        InputStream is = request.getInputStream();
        this.cachedBody = StreamUtils.copyToByteArray(is);
    }

    @Override
    public BufferedReader getReader() throws IOException {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.cachedBody);
        return new BufferedReader(new InputStreamReader(byteArrayInputStream));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new FilterServletInputStream(this.cachedBody);
    }
}

  

package com.test.filter;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

class FilterServletInputStream extends ServletInputStream {
    private InputStream inputStream;

    public FilterServletInputStream(byte[] cachedBody) {
        this.inputStream = new ByteArrayInputStream(cachedBody);
    }

    @Override
    public boolean isFinished() {
        try {
            return inputStream.available() == 0;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean isReady() {
        return true;
    }

    @Override
    public void setReadListener(ReadListener readListener) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int read() throws IOException {
        return inputStream.read();
    }
}

  3. FilterHttpServletResponse: wrapping HTTP response

package com.test.filter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

class FilterHttpServletResponse extends HttpServletResponseWrapper {

    private volatile FilterServletOutputStream outStream;
    private PrintWriter printWriter;

    public FilterHttpServletResponse(HttpServletResponse response) {
        super(response);
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        synchronized (this) {
            if (printWriter == null) {
                outStream = new FilterServletOutputStream(super.getOutputStream());
                OutputStreamWriter osw = new OutputStreamWriter(outStream,getResponse().getCharacterEncoding());
                printWriter = new PrintWriter(osw);
            }
        }
        return printWriter;
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        synchronized (this) {
            if (outStream == null) {
                outStream = new FilterServletOutputStream(super.getOutputStream());
            }
        }
        return outStream;
    }

    // 获取服务器回复内容
    public String getResponseBody() {
        return (outStream == null) ? null : new String(outStream.getWroteInfo());
    }
}

   

package com.test.filter;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

class FilterServletOutputStream extends ServletOutputStream {

    private ServletOutputStream output;
    private ByteArrayOutputStream copy=new ByteArrayOutputStream();

    public FilterServletOutputStream(ServletOutputStream output) {
        super();
        this.output = output;
    }

    @Override
    public boolean isReady() {
        return output.isReady();
    }

    @Override
    public void setWriteListener(WriteListener arg0) {
        output.setWriteListener(arg0);
    }

    @Override
    public void write(int b) throws IOException {
        output.write(b);
        copy.write(b);
    }

    @Override
    public void write(byte[] b) throws IOException {
        output.write(b);
        copy.write(b);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        output.write(b,off,len);
        copy.write(b,off,len);
    }

    public byte[] getWroteInfo() {
        return copy.toByteArray();
    }

    @Override
    public void flush() throws IOException {
        output.flush();
        copy.close();
    }

    @Override
    public void close() throws IOException {
        output.close();
        copy.close();
    }
}

reference:

Tomcat filter creation and configuration

Make getReader() and getInputStream() in HttpServletRequest reusable - Daochang - 博客园

Use of HttpServletRequestWrapper and HttpServletResponseWrapper in Filter Filter_Bitter Coffee-coffe's Blog-CSDN Blog

Guess you like

Origin blog.csdn.net/ayang1986/article/details/127772375