• Springboot:拦截器和过滤器


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

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

    过滤器:Filter

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

    示例

    1. /**
    2. * 检查用户是否已经完成登录
    3. */
    4. @WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
    5. @Slf4j
    6. public class LoginCheckFilter implements Filter{
    7. //路径匹配器,支持通配符
    8. public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
    9. @Override
    10. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    11. HttpServletRequest request = (HttpServletRequest) servletRequest;
    12. HttpServletResponse response = (HttpServletResponse) servletResponse;
    13. //1、获取本次请求的URI
    14. String requestURI = request.getRequestURI();// /backend/index.html
    15. log.info("拦截到请求:{}",requestURI);
    16. //定义不需要处理的请求路径
    17. String[] urls = new String[]{
    18. "/employee/login",
    19. "/employee/logout",
    20. "/backend/**",
    21. "/front/**"
    22. };
    23. //2、判断本次请求是否需要处理
    24. boolean check = check(urls, requestURI);
    25. //3、如果不需要处理,则直接放行
    26. if(check){
    27. log.info("本次请求{}不需要处理",requestURI);
    28. filterChain.doFilter(request,response);
    29. return;
    30. }
    31. //4、判断登录状态,如果已登录,则直接放行
    32. if(request.getSession().getAttribute("employee") != null){
    33. log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
    34. filterChain.doFilter(request,response);
    35. return;
    36. }
    37. log.info("用户未登录");
    38. //5、如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据
    39. response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
    40. return;
    41. }
    42. /**
    43. * 路径匹配,检查本次请求是否需要放行
    44. * @param urls
    45. * @param requestURI
    46. * @return
    47. */
    48. public boolean check(String[] urls,String requestURI){
    49. for (String url : urls) {
    50. boolean match = PATH_MATCHER.match(url, requestURI);
    51. if(match){
    52. return true;
    53. }
    54. }
    55. return false;
    56. }
    57. }

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

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

    拦截器:Interceptor

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

    拦截器特点

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

    拦截器作用

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

    springmvc中开发拦截器步骤

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

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

    1. package wmq.fly.mybatis.interceptor;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4. import org.springframework.stereotype.Component;
    5. import org.springframework.web.servlet.HandlerInterceptor;
    6. import org.springframework.web.servlet.ModelAndView;
    7. @Component
    8. public class LoginInterceptor implements HandlerInterceptor {
    9. /**
    10. * 预处理回调方法,实现处理器的预处理
    11. * 返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或处理器
    12. */
    13. @Override
    14. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    15. throws Exception {
    16. System.out.println("开始拦截.........");
    17. //业务代码
    18. return false;
    19. }
    20. /**
    21. * 后处理回调方法,实现处理器(controller)的后处理,但在渲染视图之前
    22. * 此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理
    23. */
    24. @Override
    25. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    26. ModelAndView modelAndView) throws Exception {
    27. // TODO Auto-generated method stub
    28. }
    29. /**
    30. * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,
    31. * 如性能监控中我们可以在此记录结束时间并输出消耗时间,
    32. * 还可以进行一些资源清理,类似于try-catch-finally中的finally,
    33. * 但仅调用处理器执行链中
    34. */
    35. @Override
    36. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    37. throws Exception {
    38. // TODO Auto-generated method stub
    39. }
    40. }

  • 相关阅读:
    KITTI数据集解析和可视化
    树状数组及扩展
    DOM系列之动画函数封装
    《ARM》cortex-A7核UART实验小作业
    vue http页面新开窗口跳转https页面
    string cow方法实现
    安装samba服务器
    TensorFlow入门(七、检查点)
    PostgreSQL:查询元数据(表 、字段)信息、库表导入导出命令
    【剑指 Offer II 003】前 n 个数字二进制中 1 的个数 c++
  • 原文地址:https://blog.csdn.net/m0_63748493/article/details/126606101