美文网首页
SpringBoot拦截器

SpringBoot拦截器

作者: hTangle | 来源:发表于2019-04-07 21:08 被阅读0次

    一般实现

    1. 定义一个拦截器类

    MyInterceptor.java 实现HandlerInterceptor 接口

    import org.json.JSONObject;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.PrintWriter;
    
    @Component
    public class MyInterceptor implements HandlerInterceptor {
        Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
    
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            // TODO Auto-generated method stub
            //获取session
            logger.info("---------------------开始进入请求地址拦截----------------------------");
            //return true;
            HttpSession session = request.getSession(true);
            if (session.getAttribute("userId") == null) {
                logger.info("------:跳转到login页面!");
    //            response.reset();
    
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=utf-8");
                PrintWriter out = null;
    
                JSONObject res = new JSONObject();
                res.put("state", "0");
                res.put("msg", "login in first");
                res.put("output","");
                out = response.getWriter();
                out.append(res.toString());
                return false;
            } else {
                session.setAttribute("userId", session.getAttribute("userId"));
                return true;
            }
        }
    
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                               ModelAndView modelAndView) throws Exception {
            // TODO Auto-generated method stub
            logger.info("--------------处理请求完成后视图渲染之前的处理操作---------------");
        }
    
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            // TODO Auto-generated method stub
            logger.info("---------------视图渲染之后的操作-------------------------0");
        }
    }
    
    

    定义一个WebConfig类,并将
    WebConfig.java

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    import javax.annotation.Resource;
    
    @Configuration
    public class WebConfig implements WebMvcConfigurer{
        @Resource
        private MyInterceptor myInterceptor;
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(myInterceptor).addPathPatterns("/sensitiveword");//.excludePathPatterns("/login.html").excludePathPatterns("/*.min.js.*");
        }
    
    }
    

    这样一个拦截器就实现了
    HandlerInterceptor是一个接口,其中定义了三个default方法

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.lang.Nullable;
    
    public interface HandlerInterceptor {
        default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            return true;
        }
    
        default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        }
    
        default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        }
    }
    

    WebMvcConfigurer也是一个接口,定义的方法都是default方法

    import java.util.List;
    import org.springframework.format.FormatterRegistry;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.lang.Nullable;
    import org.springframework.validation.MessageCodesResolver;
    import org.springframework.validation.Validator;
    import org.springframework.web.method.support.HandlerMethodArgumentResolver;
    import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
    import org.springframework.web.servlet.HandlerExceptionResolver;
    
    public interface WebMvcConfigurer {
        default void configurePathMatch(PathMatchConfigurer configurer) {
        }
        //内容协商配置
        default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        }
    
        default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        }
    
        default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        }
        //类型转换器和格式化器
        default void addFormatters(FormatterRegistry registry) {
        }
        //添加拦截器
        default void addInterceptors(InterceptorRegistry registry) {
        }
        //添加静态资源,重新定义静态资源的路径
        default void addResourceHandlers(ResourceHandlerRegistry registry) {
        }
        //添加跨域支持
        default void addCorsMappings(CorsRegistry registry) {
        }
    
        default void addViewControllers(ViewControllerRegistry registry) {
        }
        //配置视图解析器
        default void configureViewResolvers(ViewResolverRegistry registry) {
        }
    
        default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        }
    
        default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
        }
        //配置消息转换器
        default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        }
    
        default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        }
    
        default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        }
    
        default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        }
    
        @Nullable
        default Validator getValidator() {
            return null;
        }
    
        @Nullable
        default MessageCodesResolver getMessageCodesResolver() {
            return null;
        }
    }
    
    

    Servlet过滤器

    • Servlet过滤器提供过滤作用,能够在调用前检查Request对象,修改Request Header和Request内容,在Servlet调用完成以后检查Response对象,修改Response Header和Respones内容
    • 可以串联
    • 只有特定的URL才会触发拦截器
    public interface Filter {
            //Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例后将调用这个方法。在这个方法中可以读取web.xml文件中Servlet过滤器的初始化参数
        public void init(FilterConfig filterConfig) throws ServletException;
        //完成实际的过滤操作,当客户请求访问于过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain参数用于访问后续过滤器
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException;
             //Servlet容器在销毁过滤器实例前调用该方法,这个方法中可以释放Servlet过滤器占用的资源
        public void destroy();
    }
    public interface FilterConfig {
     //返回web.xml部署文件中定义的该过滤器的名称
        String getFilterName();
     //返回调用者所处的servlet上下文
        ServletContext getServletContext();
    //返回过滤器初始化参数值的字符串形式,当参数不存在时,返回nul1.name是初始化参数名
        String getInitParameter(String var1);
    //以Enumeration形式返回过滤器所有初始化参数值,如果没有初始化参数,返回为空
        Enumeration<String> getInitParameterNames();
    }
    
    

    Servlet拦截过程

    1. 拦截器截获客户端请求
    2. 重新封装ServletResponse,在封装后的ServletResponse中提供用户自定义的输出流
    3. 将请求后续传递
    4. Web组件响应请求
    5. 获取ServletRespones中的输出流
    6. 将响应内容通过用户自定义的输出流写入到缓冲流中
    7. 修改响应内容清空缓冲流输出相应内容

    对比

    • filter基于filter接口中的doFilter回调函数,interceptor则基于Java本身的反射机制;
    • filter是依赖于servlet容器的,没有servlet容器就无法回调doFilter方法,而interceptor与servlet无关;
    • filter的过滤范围比interceptor大,filter除了过滤请求外通过通配符可以保护页面、图片、文件等,而interceptor只能过滤请求,只对action起作用,在action之前开始,在action完成后结束(如被拦截,不执行action);
    • filter的过滤一般在加载的时候在init方法声明,而interceptor可以通过在xml声明是guest请求还是user请求来辨别是否过滤;
    • interceptor可以访问action上下文、值栈里的对象,而filter不能;
    • 在action的生命周期中,拦截器可以被多次调用,而过滤器只能在容器初始化时被调用一次。

    相关文章

      网友评论

          本文标题:SpringBoot拦截器

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