SpringMVC的拦截器和过滤器的区别与联系

SpringMVC的拦截器和过滤器的区别与联系,第1张

拦截器与过滤器的区别 :

拦截器是基于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中如何配置基础拦截器等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10638492.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-10
下一篇 2023-05-10

发表评论

登录后才能评论

评论列表(0条)

保存