拦截器与过滤器的区别 :
拦截器是基于java的反射机制的,而过滤器是基于函数回调。
拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些 *** 作。
过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息。
区别主要以下几点:
1spring的拦截器与Servlet的Filter有相似之处,比如二者都是AOP编程思想的体现,都能实现权限检查、日志记录等。不同的是:
2使用范围不同:Filter是Servlet规范规定的,只能用于Web程序中。而拦截器既可以用于Web程序,也可以用于Application、Swing程序中。
3规范不同:Filter是在Servlet规范中定义的,是Servlet容器支持的。而拦截器是在Spring容器内的,是Spring框架支持的。
4深度不同:Filter在只在Servlet前后起作用。而拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用具有更大的d性。所以在Spring构架的程序中,要优先使用拦截器。
顺序就是Spring filter先执行的。
所有的开发之中拦截器一定是一个必须要使用的功能,利用拦截器可以更加有效的实现数据的验证处理,而且最为幸运的是在SpringBoot之中所使用的拦截器与Spring中的拦截器完全一样。
基础拦截器 *** 作
拦截器是一种AOP *** 作实现,那么在AOP之中用户一定不需要去关注拦截器的存在,用户只需要按照自己已经习惯的处理方式进行代码的编写即可。
创建一个程序的控制器类:
package comgwolfcontroller;
import comgwolfutilcontrollerAbstractBaseController;
import comgwolfvoMember;
import orgspringframeworkstereotypeController;
import orgspringframeworkuiModel;
import orgspringframeworkwebbindannotationRequestMapping;
import orgspringframeworkwebbindannotationRequestMethod;
import orgspringframeworkwebbindannotationResponseBody;
@Controller
public class MemberController extends AbstractBaseController{
@RequestMapping(value="/member_add_pre", method = RequestMethodGET)
public String memberAddPre() {
return "member_add";
}
@RequestMapping(value="/member_add", method = RequestMethodPOST)
@ResponseBody
public Object memberAdd(Member member) {
return member;
}
}
定义一个member_addhtml的页面实现表单定义:
<!DOCTYPE html>
<html xmlns:th=">
<head>
<title>SpringBoot模板渲染</title>
<link rel="icon" type="image/x-icon"
href="/images/baiduico" />
<meta >
content="text/html;charset=UTF-8" />
</head>
<body>
<form th:action="@{/member_add}" method="post">
用户编号:<input type="text" name="mid" value="101">
用户姓名:<input type="text" name="name" value="SMITH">
<input type="submit" value="表单提交">
</form>
</body>
</html>
此时一个正常的MVC的代码就实现完成了,随后需要编写一个拦截器对其进行控制。为了更好的说明问题,现在将拦截器定义在外包中:
package comgwolfutil;
import orgslf4jLogger;
import orgslf4jLoggerFactory;
import orgspringframeworkwebmethodHandlerMethod;
import orgspringframeworkwebservletHandlerInterceptor;
import orgspringframeworkwebservletModelAndView;
import javaxservlet>
import javaxservlet>
public class MyInterceptor implements HandlerInterceptor{
private Logger log = LoggerFactorygetLogger(MyInterceptorclass);
@Override
public boolean preHandle(>
>
HandlerMethod handlerMethod = (HandlerMethod)handler;
thisloginfo("[MyInterceptorpreHandle" + handlerMethodgetBean()getClass()getSimpleName());
return true;
}
@Override
public void postHandle(>
>
ModelAndView modelAndView) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod)handler;
thisloginfo("[MyInterceptorpostHandle" + handlerMethodgetBean()getClass()getSimpleName());
thisloginfo("[MyInterceptorpostHandle" + modelAndView);
}
@Override
public void afterCompletion(>
HandlerMethod handlerMethod = (HandlerMethod)handler;
thisloginfo("[MyInterceptorafterCompletion拦截结束" );
}
}
那么此时如果要想使用拦截器则必须有一个拦截器的配置类。现在不再编写配置文件了,所有的配置直接利用一个类完成。
package comgwolfconfig;
import comgwolfutilMyInterceptor;
import orgspringframeworkcontextannotationConfiguration;
import orgspringframeworkwebservletconfigannotationInterceptorRegistry;
import orgspringframeworkwebservletconfigannotationWebMvcConfigurerAdapter;
//定义mvc配置
@Configuration
public class MyWebApplicationConfig extends WebMvcConfigurerAdapter{
@Override
public void addInterceptors(InterceptorRegistry registry) {
registryaddInterceptor(new MyInterceptor())addPathPatterns("/");
superaddInterceptors(registry);
}
}
// 只拦截action
// 不要拦截jsp文件,如果一定要拦截某个目录下的jsp,则需要写专门的filter而一旦拦截了jsp,则jsp对应的js,css,image,均不能访问
完成
应用场景
1、日志记录,可以记录请求信息的日志,以便进行信息监控、信息统计等。
2、权限检查:如登陆检测,进入处理器检测是否登陆,如果没有直接返回到登陆页面。
3、性能监控:典型的是慢日志。
拦截器我想大家都并不陌生,最常用的登录拦截、或是权限校验、或是防重复提交、或是根据业务像12306去校验购票时间,总之可以去做很多的事情。
定义一个Interceptor 非常简单方式也有几种,我这里简单列举两种
1、类要实现Spring 的HandlerInterceptor 接口
2、类继承实现了HandlerInterceptor 接口的类,例如 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter
preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;
postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView (这个博主就基本不怎么用了);
afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面);
------------
这样在我们业务中比如要记录系统日志,日志肯定是在afterCompletion之后记录的,否则中途失败了,也记录了,那就扯淡了。一定是程序正常跑完后,我们记录下那些对数据库做个增删改的 *** 作日志进数据库。所以我们只需要继承HandlerInterceptorAdapter,并重写afterCompletion一个方法即可,因为preHandle默认是true。
运行流程总结如下:
1、拦截器执行顺序是按照Spring配置文件中定义的顺序而定的。
2、会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则按顺序加载完preHandle方法。
3、然后执行主方法(自己的controller接口),若中间抛出异常,则跟return false效果一致,不会继续执行postHandle,只会倒序执行afterCompletion方法。
4、在主方法执行完业务逻辑(页面还未渲染数据)时,按倒序执行postHandle方法。若第三个拦截器的preHandle方法return false,则会执行第二个和第一个的postHandle方法和afterCompletion(postHandle都执行完才会执行这个,也就是页面渲染完数据后,执行after进行清理工作)方法。(postHandle和afterCompletion都是倒序执行)
WebMvcConfigurer配置类其实是Spring内部的一种配置方式,采用JavaBean的形式来代替传统的xml配置文件形式进行针对框架个性化定制,可以 自定义一些Handler,Interceptor,ViewResolver,MessageConverter 。基于java-based方式的spring mvc配置,需要创建一个 配置 类并实现 WebMvcConfigurer 接口;
在Spring Boot 15版本都是靠重写 WebMvcConfigurerAdapter 的方法来添加自定义拦截器,消息转换器等。SpringBoot 20 后,该类被标记为@Deprecated(弃用)。官方推荐直接实现WebMvcConfigurer或者直接继承WebMvcConfigurationSupport,方式一 实现WebMvcConfigurer接口( 推荐),方式二继承WebMvcConfigurationSupport类
其中常用的方法:
以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面,感觉好麻烦,其实重写WebMvcConfigurer中的addViewControllers方法即可达到效果了
值的指出的是,在这里重写addViewControllers方法,并不会覆盖 WebMvcAutoConfiguration (Springboot自动配置)中的addViewControllers(在此方法中,Spring Boot将“/”映射至indexhtml),这也就意味着 自己的配置和Spring Boot的自动配置同时有效 ,这也是我们推荐添加自己的MVC配置的方式。
比如,我们想 自定义静态资源映射目录 的话,只需重写addResourceHandlers方法即可。
注:如果继承WebMvcConfigurationSupport类实现配置时必须要重写该方法,具体见其它文章
此时会注册一个默认的Handler:DefaultServlet>
步骤如下: 1、编写要引用的程序集。 我们几乎可以编写任何用途的程序集,就像用C#开发net类库一样。不过需要注意的是,如果要编写从Unity继承的类(比如从MonoBehaviour派生的组件等等)
以上就是关于SpringMVC的拦截器和过滤器的区别与联系全部的内容,包括:SpringMVC的拦截器和过滤器的区别与联系、Spring filter和拦截器的区别和执行顺序、在SpringBoot中如何配置基础拦截器等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)