亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

spring boot 添加自定義監聽器、過濾器、攔截器

標簽:
SpringBoot

场景1:需要项目启动的时候把数据加载到缓存中去 使用:监听器

1.自定义listenner类 添加@WebListener 实现ServletContextListener


webp

一个注解 一个实现


2.重写contextInitialized方法

    @Override
    public void contextInitialized(ServletContextEvent sce) {  //当服务启动时候的业务逻辑

    }

3.在启动类添加注解扫描
@EnableScheduling
@ServletComponentScan


webp

指定扫描类

场景2:在Rest接口中,在拦截器位置判断请求体的参数是否签名符合规范,符合放行在handler中进行业务逻辑的处理,不符合直接不进行响应 使用:过滤器+拦截器

这类功能有一些点还是需要注意的

  • 过滤器请求被处理前调用一次,拦截器可以调用多次

  • 过滤器无法直接响应请求

  • 过滤器和拦截器中httpServletRequest中getInputStream()只可读取一次,无法重复读取

想要在拦截器中读取输入流之后,handler依旧可以再次读取输入流需要在过滤器中读取inputStream,之后缓存起来,然后包装httpServletRequest;重写其中getInputStream()方法去拿缓存数据,就可以满足在拦截器处理getInputStream之后,handler依旧可以从httpServletRequest中拿到数据

1.过滤器处理

//过滤顺序@Order(1)//过滤器配置@WebFilter(filterName = "xxxRequestFilter", urlPatterns = "/path/*")public class xxxRequestFilter implements Filter {    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {        if (!(request instanceof ApiRequestWrapper)) {//XXXRequestWrapper是HttpServletRequest包装类
            XXXRequestWrapper xxxRequestWrapper = new XXXRequestWrapper((HttpServletRequest) request);
            chain.doFilter(xxxRequestWrapper, response);            return;
        }
        chain.doFilter(request,response);
    }    @Override
    public void destroy() {

    }
}

2.XXXRequestWrapper包装HttpServletRequest 缓存数据

public class XXXRequestWrapper extends HttpServletRequestWrapper {    
    private byte[] rawData;    private HttpServletRequest request;    private ResettableServletInputStream servletStream;    public XXXRequestWrapper(HttpServletRequest request) {        super(request);        this.request = request;        this.servletStream = new ResettableServletInputStream();

    }    public void resetInputStream() {
        servletStream.stream = new ByteArrayInputStream(rawData);
    }    @Override
    public ServletInputStream getInputStream() throws IOException {        if (rawData == null) {
            rawData = readBytes(request).getBytes(Charset.forName("UTF-8"));
            servletStream.stream = new ByteArrayInputStream(rawData);
        }        return servletStream;
    }    @Override
    public BufferedReader getReader() throws IOException {        if (rawData == null) {
            rawData = readBytes(request).getBytes(Charset.forName("UTF-8"));
            servletStream.stream = new ByteArrayInputStream(rawData);
        }        return new BufferedReader(new InputStreamReader(servletStream));
    }    private class ResettableServletInputStream extends ServletInputStream {        private InputStream stream;        @Override
        public int read() throws IOException {            return stream.read();
        }        @Override
        public boolean isFinished() {            return false;
        }        @Override
        public boolean isReady() {            return false;
        }        @Override
        public void setReadListener(ReadListener listener) {

        }
    }    private String readBytes(HttpServletRequest request){
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line;            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {            if (inputStream != null) {                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }            if (reader != null) {                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }        return sb.toString();
    }    public String getBodyString() {        try {            return new String(rawData, "UTF-8");
        } catch (UnsupportedEncodingException ex) {            return new String(rawData);
        }
    }
 
}

3.拦截器Interceptor

@Componentpublic class XXXRequestInterceptor implements HandlerInterceptor {    protected Logger log = LoggerFactory.getLogger(getClass());    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {         if (httpServletRequest instanceof XXXRequestWrapper) {
             XXXRequestWrapper xxxRequestWrapper = (XXXRequestWrapper) httpServletRequest;          //使用getInputStream 不影响后续的处理器获取请求体中的数据
             xxxRequestWrapper.getInputStream();
              log.info("校验成功 ");
             }catch (Exception e) {
                 log.error("请求校验失败 ");                 return false;
             }        return true;
    }    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

4.其他配置

拦截器不需要单独添加注解,在类上添加@Component即可
过滤器需要在启动类上配置

@ServletComponentScan(basePackageClasses={xxx.xxxRequestFilter.class})



作者:VincentPeng
链接:https://www.jianshu.com/p/b8a6dd1eb9de


點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消