前言中招的朋友应该都听说过过滤器、拦截器、切面,它们都有拦截拦截的作用。在做一些业务需求的时候,不知道该如何选择。下面介绍一下它们的区别。Filter过滤器可以拦截方法的请求和响应(ServletRequest请求,ServletResponse响应),过滤请求响应。过滤器取决于servlet容器。在实现上,基于函数回调,可以过滤几乎所有的请求,并且一个过滤器实例只能在容器初始化时被调用一次。使用过滤器的目的是做一些过滤操作,得到我们想要获取的数据,比如:修改过滤器中的字符编码;修改过滤器中HttpServletRequest的部分参数,包括:过滤粗俗文字、危险字符等。话不多说,先上传代码然后定义两个Controller,一个UserController和一个OrderController。虽然已经定义了Filter过滤器和Controller请求,但是过滤器现在不起作用。您需要配置过滤器。有两种选择。第一个选项是将@Component@ComponentpublicclassTimeFilterimplementsFilter添加到Filter。第二个选项是配置注册过滤器。第二个选项的特点是可以细化过滤哪些规则的URL。当应用程序启动时,过滤器被初始化并回调init函数。请求http://localhost:9000/order/1查看控制台的日志输出请求http://localhost:9000/user/1控制台的日志输出应用停止后,控制台输出Filter随着filter的启动Web应用程序,仅初始化一次,并在Web应用程序停止时销毁。1、启动服务器时加载过滤器的实例,并调用init()方法初始化实例;2、每次请求处理只调用方法doFilter();3.停止服务器时调用destroy()方法销毁实例。我们看一下doFilter的方法doFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)从参数中可以看出在filter中可以获取到请求参数和响应数据;但是这个方法无法知道执行的是哪个Controller类的哪个方法。另外需要注意的是注入的bean不能在filter中使用,即上面代码@Autowired注入的值不能为null。为什么是这样?其实在Spring中,web应用的启动顺序是:listener->filter->servlet,先初始化listener,再初始化filter,再初始化我们的dispathServlet。因此,当我们需要注入一个被注解的bean时,注入就会失败,因为在初始化过滤器的时候,注解的bean还没有初始化,无法注入。如果一定要用,需要做一些处理,可以私信老顾。Interceptor拦截器依赖于web框架,在SpringMVC中依赖于SpringMVC框架。在实现上,基于Java的反射机制是面向切面编程(AOP)的一种应用,即在方法之前调用方法,或者在方法之后调用方法。在WebMvcConfigurationSupport中配置执行结果,我们发现在拦截器中可以获取到Controller对象preHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)。对象处理程序是控制器方法对象HandlerMethodhandlerMethod=(HandlerMethod)handler;handlerMethod.getBean().getClass().getName();//获取类名handlerMethod.getMethod().getName();//获取到方法名但是我们发现获取不到方法的参数值,这是为什么呢?在DispatcherServlet类中,执行了方法doDispatch(HttpServletRequestrequest,HttpServletResponseresponse)applyPreHandle方法,这是被执行的拦截器的preHandler方法,但是在这个过程中,controller方法并没有从request中获取request参数并组装方法参数;但是在使用ha.handle方法的时候,参数会被组装起来。虽然获取不到方法的参数,但是可以获取到IOCbean。还有一点要说明的是postHandler方法postHandler方法的执行。当controller内部出现异常时,posthandler方法将不会被执行。afterCompletion方法,不管controller内部是否有异常,都会执行这个方法;此方法还将有一个Exceptionex参数;如果有异常,ex就会有一个异常值;如果没有异常,则值为null注意如果controller内部有异常,但是如果异常被@ControllerAdvice统一捕获,ex也会对nullAspect的AOP操作进行切片,横向拦截操作。最大的好处是可以获取执行方法的参数,统一处理方法。在上面常用到日志、事务、请求参数安全校验的代码中,我们可以获取到方法参数。aspectaop虽然可以获取方法参数,但是不能获取response和request对象。总结让我们在这里总结一下过滤器、拦截器和方面,看看它们之间的区别。如果三个方法同时使用,它们的执行顺序是怎样的?filter->interceptor->ControllerAdvice->aspect->controller返回值顺序,或者异常返回顺序controller->aspect->controllerAdvice->Interceptor->Filter用一张图来描述执行顺序。朋友们可以根据自己的业务,并根据以上技术各自的特点,选择相应的技术。今天老顾的介绍就到这里,谢谢!!!
