前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot中使用拦截器和过滤器拦截请求并且使用包装类包装request

Spring Boot中使用拦截器和过滤器拦截请求并且使用包装类包装request

作者头像
我的小熊不见了丶
发布2019-05-23 01:02:52
1.9K0
发布2019-05-23 01:02:52
举报
文章被收录于专栏:晓月寒·晓月寒·

拦截器

在Spring Boot中使用拦截器和过滤器可以帮助我们解决很多通用性的问题。使用拦截器只需要重写preHandle方法。

代码语言:javascript
复制
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {

问题

在进行拦截时我们一般都需要解析HttpServletRequest中的流信息,但是HttpServletRequest 只能被读取一次,如果在拦截器中被读取了那么在后续的程序中就无法使用request了。因此我们需要使用包装类包装request

包装类

以下是包装类的代码:

代码语言:javascript
复制
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {

    private final byte[] body;

    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        body = IOUtil.readByteArray(request.getInputStream());
    }

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

    @Override
    public ServletInputStream getInputStream() {

        final ByteArrayInputStream bais = new ByteArrayInputStream(body);

        return new ServletInputStream() {

            @Override
            public int read() {
                return bais.read();
            }

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

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

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

代码中用到了一个工具方法:

代码语言:javascript
复制
public static byte[] readByteArray(InputStream in) throws IOException {
        BufferedInputStream bufin = new BufferedInputStream(in);
        int buffSize = 1024;
        ByteArrayOutputStream out = new ByteArrayOutputStream(buffSize);
        byte[] temp = new byte[buffSize];
        boolean var5 = false;

        int size;
        while((size = bufin.read(temp)) != -1) {
            out.write(temp, 0, size);
        }

        bufin.close();
        return out.toByteArray();
    }

上面的代码中,将原始的HttpServletRequest通过构造方法传进去保存起来,读取的时候直接读取包装类中保存的流。

代码语言:javascript
复制
if (request instanceof BodyReaderHttpServletRequestWrapper) {
            String body = IOUtil.readStream(request.getInputStream(), "UTF-8");
}

问题是在什么地方去把HttpServletRequest转换成我们自己的BodyReaderHttpServletRequestWrapper

过滤器

在Java中实现Filter,对所有请求进行过滤。

代码语言:javascript
复制
@Component
@WebFilter(value = "/*")
public class WrapRequestFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        if (servletRequest.getContentType() != null && servletRequest.getContentType().contains("application/json")) {
             //包装request
            filterChain.doFilter(new BodyReaderHttpServletRequestWrapper(request), servletResponse);
        } else {//不进行包装
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {

    }
}

如果符合条件就使用包装类。这样就把所有的接口都包装成我们自己的包装类了。然后就可以随心所欲的使用request做你想做的事情了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.02.25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 拦截器
  • 问题
  • 包装类
  • 过滤器
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档