在项目的开发中,在某些情况下,我们需要对客户端发出的请求进行拦截,常用的API拦截方式有Fliter,Interceptor,ControllerAdvice以及Aspect。

请求从Filter-->>Controller的过程中,只要在指定的环节出现异常,可以通过对应的机制进行处理。反之在任何一个环节如果异常未处理则不会进入下一个环节,会直接往外抛,例如在ControllerAdvice验证发生异常则会抛给Filter,如果Filter未处理,则最终会由Tomcat容器抛出。

过滤器:Filter

可以获得Http原始的请求和响应信息,但是拿不到响应方法的信息。
注册Filter,在springboot当中提供了FilterRegistrationBean类来注册Filter

示例

/**  * 检查用户是否已经完成登录  */ @WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*") @Slf4j public class LoginCheckFilter implements Filter{     //路径匹配器,支持通配符     public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();      @Override     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {         HttpServletRequest request = (HttpServletRequest) servletRequest;         HttpServletResponse response = (HttpServletResponse) servletResponse;          //1、获取本次请求的URI         String requestURI = request.getRequestURI();// /backend/index.html          log.info("拦截到请求:{}",requestURI);          //定义不需要处理的请求路径         String[] urls = new String[]{                 "/employee/login",                 "/employee/logout",                 "/backend/**",                 "/front/**"         };           //2、判断本次请求是否需要处理         boolean check = check(urls, requestURI);          //3、如果不需要处理,则直接放行         if(check){             log.info("本次请求{}不需要处理",requestURI);             filterChain.doFilter(request,response);             return;         }          //4、判断登录状态,如果已登录,则直接放行         if(request.getSession().getAttribute("employee") != null){             log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));             filterChain.doFilter(request,response);             return;         }          log.info("用户未登录");         //5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据         response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));         return;      }      /**      * 路径匹配,检查本次请求是否需要放行      * @param urls      * @param requestURI      * @return      */     public boolean check(String[] urls,String requestURI){         for (String url : urls) {             boolean match = PATH_MATCHER.match(url, requestURI);             if(match){                 return true;             }         }         return false;     } }

最后在Springboot主启动类中添加@ServletComponentScan

@Slf4j @SpringBootApplication @ServletComponentScan //使用过滤器需加此注解 public class ReggieApplication {     public static void main(String[] args) {         SpringApplication.run(ReggieApplication.class,args);         log.info("项目启动成功...");     } }

拦截器:Interceptor

可以获得Http原始的请求和响应信息,也拿得到响应方法的信息,但是拿不到方法响应中的参数的值。
在web开发中,拦截器是经常用到的功能。它可以帮我们验证是否登陆、预先设置数据以及统计方法的执行效率等。在spring中拦截器有两种,第一种是HandlerInterceptor,第二种是MethodInterceptor。HandlerInterceptor是SpringMVC中的拦截器,它拦截的是Http请求的信息,优先于MethodInterceptor。而MethodInterceptor是springAOP的。前者拦截的是请求的地址,而后者是拦截controller中的方法

拦截器特点

1.请求到达经过拦截器,响应回来也经过拦截器
2.只能拦截控制器相关请求不能拦截JSP请求
3.拦截器可以中断用户请求轨迹

拦截器作用

将多个控制器中共有代码放入拦截器可以减少控制器代码冗余

springmvc中开发拦截器步骤

1.实现HandlerInterceptor接口(或继承其实现类)或者实现实现WebRequestInterceptor(或继承其实现类)。
2.XML文件中配置拦截器

创建一个拦截器实现HandlerInterceptor接口

package wmq.fly.mybatis.interceptor;  import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;  @Component public class LoginInterceptor implements HandlerInterceptor {     /**      * 预处理回调方法,实现处理器的预处理      * 返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或处理器    */     @Override     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)             throws Exception {         System.out.println("开始拦截.........");         //业务代码         return false;     }       /**      * 后处理回调方法,实现处理器(controller)的后处理,但在渲染视图之前      * 此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理      */     @Override     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,             ModelAndView modelAndView) throws Exception {         // TODO Auto-generated method stub      }     /**      * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,      * 如性能监控中我们可以在此记录结束时间并输出消耗时间,      * 还可以进行一些资源清理,类似于try-catch-finally中的finally,      * 但仅调用处理器执行链中      */     @Override     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)             throws Exception {         // TODO Auto-generated method stub      }  }