美文网首页
spring boot 自定义过滤器

spring boot 自定义过滤器

作者: 只想做个俗人_贪财_好色 | 来源:发表于2022-07-23 21:35 被阅读0次

自定义过滤器:

1、首先需要实现 Filter 重写 doFilter 方法
2、doFilter 内部逻辑
  2.1、通过 servletRequest 转成 HttpServletRequestWrapper 包装
  2.2、通过spring 提供的 StreamUtils 把流信息转成字符串
  2.3、过滤链进行继续传递

注意:
filterChain.doFilter 继续传递的request 是自定义的 HttpServletRequestWrapper
因为servletRequest中的流只能读取一次,流中的信息读取是通过offset 位移来读取 经过一次读取后 offset 没有提供接口进行重置(流本身是可以通过reset进行重置的, 但是CoyoteInputStream 这个流是没有提供接口的),所以不能重置无法重复读取
补充: inputStream 提供 三个相关接口 markSupported 是否支持标记默认为false 不支持标记 mark 标记位置 reset 重置到标记位置 进行重复读取
因此 需要自定义 HttpServletRequestWrapper 把数据信息存储 成 byte[] 数组中 ,方便以后重复读取

代码示例:

@Component
@WebFilter(urlPatterns = "/*",filterName = "customFileter")
public class CustomFileter implements Filter {

    Logger logger = LoggerFactory.getLogger(CustomFileter.class);


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //获取 输入流
        CustomHttpServletRequestWrapper requestWrapper = new CustomHttpServletRequestWrapper((HttpServletRequest) servletRequest);
        //流转成字符串
        String  body =  StreamUtils.copyToString(requestWrapper.getInputStream(), Charset.forName(servletRequest.getCharacterEncoding()));
        //输出看一下 流中的信息
        logger.info(body);
        //继续执行过滤链
        filterChain.doFilter(requestWrapper,servletResponse);
    }
}

自定义 HttpServletRequestWrapper

1、首先需要继承 HttpServletRequestWrapper 在构造函数中把request流存储到 byte[] 数组中,此时 旧的request的流信息已经不能重复读取了
2、重写 getInputStream 方法 把 byte[] 数组转成 新的流 返回 新的 ServletInputStream
3、重写 返回 ServletInputStream 对象中的 read() 方法 需要在 新的流中读取

class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {

    /**
     * 定义 byte数组
     */
    private final byte[] requestBody;

    public CustomHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        //把流数据 转到数组保存
        requestBody = StreamUtils.copyToByteArray(request.getInputStream());
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    /**
     * getInputStream 从byte数组中获取数据转成流
     * @return ServletInputStream
     */
    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream inputStream = new ByteArrayInputStream(requestBody);

        return  new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

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

            @Override
            public void setReadListener(ReadListener readListener) {

            }

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

    }
}

相关文章

网友评论

      本文标题:spring boot 自定义过滤器

      本文链接:https://www.haomeiwen.com/subject/renbirtx.html