1. 过滤器

Filter介绍

Filter可以认为是Servlet的一种“加强版”,是对Servlet的扩展(既可以对请求进行预处理,又可以对处理结果进行后续处理。使用Filter完整的一般流程是:Filter对用户请求进行【预处理】,接着将请求交给Servlet进行预处理并【生成响应】,最后Filter再对服务器响应进行【后处理】。

Filter的优点

  • 在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。
  • 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
  • 在HttpServletResponse到达客户端之前,拦截HttpServletResponse。
  • 根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

Filter的应用场景

  • 用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求。
  • 日志Filter:详细记录某些特殊的用户请求。
  • 负责解码的Filter,包括对非标准编码的请求解码。
  • 能改变XML内容的XSLT Filter等。
  • Filter可以负责拦截多个请求或响应;一个请求或响应也可以被多个Filter拦截。

创建Filter

  1. 创建Filter处理类(实现javax.servlet.Filter接口)
  • void init(FilterConfig config):用于完成Filter的初始化。
  • void destory():用于Filter销毁前,完成某些资源的回收。
  • void doFilter(ServletRequest request,ServletResponse response,FilterChain chain):实现过滤功能,该方法就是对每个请求及响应增加的额外处理。该方法可以实现对用户请求进行预处理(ServletRequest request),也可实现对服务器响应进行后处理(ServletResponse response)—它们的分界线为是否调用了chain.doFilter(),执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理。
  1. web.xml文件中配置Filter

Filter 示例

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class DemoApplication { public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
} //to visit http://localhost:8080/filter/say
}
package com.example.demo.configuration;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; /**
* 使用spring boot提供的FilterRegistrationBean注册Filter
*
*/
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("MyFilter init");
} @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
// do something 处理request 或response
System.out.println("MyFilter doFilter"); // 调用filter链中的下一个filter
filterChain.doFilter(servletRequest, servletResponse);
} @Override
public void destroy() {
System.out.println("MyFilter destroy");
}
}
package com.example.demo.configuration;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /***
* 使用spring boot提供的FilterRegistrationBean注册Filter
*
*/
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean registrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean;
}
}
package com.example.demo.configuration;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter; import org.springframework.stereotype.Component;
/**
* 方式二
* 使用原生servlet注解定义Filter
*
*/
//注入spring容器
@Component
// 定义filterName 和过滤的url
@WebFilter(filterName = "my2Filter", urlPatterns = "/*")
public class My2Filter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("MyFilter2 init");
} @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
System.out.println("MyFilter2 doFilter"); // 调用filter链中的下一个filter
filterChain.doFilter(servletRequest, servletResponse);
} @Override
public void destroy() {
System.out.println("MyFilter2 destroy");
}
}
package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/filter")
public class DomainController { @RequestMapping(value="say", method=RequestMethod.GET)
public void say(){
System.out.println("ok");
}
}
server.port = 8080
server.context-path=/ # tomcat相关设置
server.tomcat.uri-encoding=UTF-8

2. 拦截器

Interceptor介绍

拦截器,在AOP(Aspect-Oriented Programming)中用于在【某个方法或字段被访问】之前进行拦截,然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。拦截器是**动态拦截Action调用的对象**。它提供了一种机制可以使开发者可以定义在一个Action执行的前后执行的代码,也可以在一个Action执行前阻止其执行。同时也提供了一种可以提取Action中可重用的部分的方式。

拦截器**将Action共用的行为独立出来,在Action执行前后执行**。这也就是我们所说的AOP,它是分散关注的编程方法,它将通用需求功能从不相关类之中分离出来;同时,能够共享一个行为,一旦行为发生变化,不必修改很多类,只要修改这个行为就可以。

拦截器将很多功能从我们的Action中独立出来,大量减少了我们Action的代码,独立出来的行为就有很好的重用性。

当你提交对Action(默认是.action结尾的url)的请求时,ServletDispatcher会根据你的请求,去调度并执行相应的Action。在Action执行之前,调用被Interceptor截取,Interceptor在Action执行前后执行。

创建Interceptor必须实现com.opensymphony.xwork2.interceptor.Interceptor接口,该接口定义了如下三个方法。

  • void init():在该拦截器被实例化之后,在该拦截器执行拦截之前,系统将回调该方法。对于每个拦截器而言,其init()方法只执行一次。因此,该方法的方法体主要用于初始化资源。
  • void destory():该方法与init()方法对应。在拦截器实例被销毁之前,系统将回调该拦截器的destory方法,该方法用于销毁在init方法里打开的资源。
  • String intercept(ActionInvocation invocation):该方法是用户需要实现的拦截动作。就像Action的execute方法一样。intercept方法会返回一个字符串作为逻辑视图。如果该方法直接返回了一个字符串,系统会将跳转到该逻辑视图对应的实际视图资源,不会调用被拦截的Action。该方法的ActionInvocation参数包含了被拦截的Action的引用,可以通过调用该参数的invoke方法,将控制权转给下一个拦截器,或者转给Action的execute方法(如果该拦截器后没有其他拦截器,则直接执行Action的execute方法)。
     

拦截器示例

package com.example.demo.interceptor.configuration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import com.beust.jcommander.internal.Nullable; /**
* 定义拦截器
*
*/
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("MyInterceptor preHandle");
return true;
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView)
throws Exception {
System.out.println("MyInterceptor postHandle");
} @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex)
throws Exception {
System.out.println("MyInterceptor afterCompletion");
}
}
package com.example.demo.interceptor.configuration;

import java.util.List;

import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /**
* 配置拦截器
*
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer{
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor());
} @Override
public void configurePathMatch(PathMatchConfigurer configurer) {
// TODO Auto-generated method stub } @Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// TODO Auto-generated method stub } @Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
// TODO Auto-generated method stub } @Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
// TODO Auto-generated method stub } @Override
public void addFormatters(FormatterRegistry registry) {
// TODO Auto-generated method stub } @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// TODO Auto-generated method stub } @Override
public void addCorsMappings(CorsRegistry registry) {
// TODO Auto-generated method stub } @Override
public void addViewControllers(ViewControllerRegistry registry) {
// TODO Auto-generated method stub } @Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// TODO Auto-generated method stub } @Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
// TODO Auto-generated method stub } @Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
// TODO Auto-generated method stub } @Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// TODO Auto-generated method stub } @Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// TODO Auto-generated method stub } @Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
// TODO Auto-generated method stub } @Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
// TODO Auto-generated method stub } @Override
public Validator getValidator() {
// TODO Auto-generated method stub
return null;
} @Override
public MessageCodesResolver getMessageCodesResolver() {
// TODO Auto-generated method stub
return null;
}
}

3. Filter和Interceptor的区别

  • Filter是基于函数回调的,而Interceptor则是基于Java反射的。
  • Filter依赖于Servlet容器,而Interceptor不依赖于Servlet容器。
  • Filter对几乎所有的请求起作用,而Interceptor只能对action请求起作用。
  • Interceptor可以访问Action的上下文,值栈里的对象,而Filter不能。
  • 在action的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。

4. Filter和Interceptor的执行顺序

过滤前-拦截前-action执行-拦截后-过滤后

MyFilter doFilter
MyFilter2 doFilter
MyInterceptor preHandle
ok
MyInterceptor postHandle
MyInterceptor afterCompletion
MyFilter doFilter
MyFilter2 doFilter

过滤器拦截器运行先后步骤

5. 普通的可以使用反射

反射的应用 3 动态代理+切面编程 AOP代理

        // 11. 反射的应用 3 动态代理+切面编程 AOP代理
// 在调用指定方法之前和之后调用preAction()和postAction()方法
SuperMan man = new SuperMan();//创建一个被代理类的对象 Human human = (Human) ManProxy.getProxyInstance(man);//返回一个代理类的对象
human.info();//通过代理类的对象嗲用重写的抽象的方法 System.out.println();
human.fly();
interface Human {
void info();
void fly();
} class SuperMan implements Human {
@Override
public void info() {
System.out.println("我是超人!");
} @Override
public void fly() {
System.out.println("I believe I can fly!");
}
} class HumanUtil {
public void preAction() {
System.out.println("=============preAction()============");
} public void postAction() {
System.out.println("=============postAction()============");
}
} class ManInvocationHandler implements InvocationHandler {
Object object; public void setObject(Object object) {
this.object = object;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
HumanUtil h = new HumanUtil(); h.preAction();
Object returnVal = method.invoke(object, args);
h.postAction(); return returnVal;
}
} //动态的创建一个代理类的对象
class ManProxy {
public static Object getProxyInstance(Object object) {
ManInvocationHandler handler = new ManInvocationHandler();
handler.setObject(object); return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), handler);
}
}

Spring boot 拦截器和过滤器的更多相关文章

  1. 面试题:struts 拦截器和过滤器

    拦截器和过滤器的区别 过滤器是servlet规范中的一部分,任何java web工程都可以使用. 拦截器是struts2框架自己的,只有使用了struts2框架的工程才能用. 过滤器在url-patt ...

  2. Spring boot拦截器的实现

    Spring boot拦截器的实现 Spring boot自带HandlerInterceptor,可通过继承它来实现拦截功能,其的功能跟过滤器类似,但是提供更精细的的控制能力. 1.注册拦截器 @C ...

  3. 【spring boot】spring boot 拦截器

    今日份代码: 1.定义拦截器 import com.alibaba.fastjson.JSON; import org.apache.commons.collections.CollectionUti ...

  4. Spring Boot2(七):拦截器和过滤器

    一.前言 过滤器和拦截器两者都具有AOP的切面思想,关于aop切面,可以看上一篇文章.过滤器filter和拦截器interceptor都属于面向切面编程的具体实现. 二.过滤器 过滤器工作原理 从上图 ...

  5. spring boot拦截器配置

    1.在spring boot配置文件application.properties中添加要拦截的链接 com.url.interceptor=/user/test 2.编写拦截器代码 ,创建UrlInt ...

  6. Spring拦截器和过滤器

    什么是拦截器 拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在方法执行之前或之后加入某些操作,其实就是AOP的一种实现策略.它通过动态拦截Action调用的对象,允许开发者 ...

  7. spring boot拦截器WebMvcConfigurerAdapter,以及高版本的替换方案(转)

    文章转自 http://blog.51cto.com/12066352/2093750 最近项目采用spring icloud,用的spring boot版本是1.5.x的,spring boot 2 ...

  8. SpringMVC学习笔记:拦截器和过滤器

    首先说明一下二者的区别: 1. 拦截器基于java的反射机制,而过滤器是基于函数回调 2. 拦截器不依赖于servlet容器,过滤器依赖servlet容器 3. 拦截器只能对action请求起作用,而 ...

  9. spring boot拦截器WebMvcConfigurerAdapter,以及高版本的替换方案

    Springboot中静态资源和拦截器处理(踩了坑)   背景: 在项目中我使用了自定义的Filter 这时候过滤了很多路径,当然对静态资源我是直接放过去的,但是,还是出现了静态资源没办法访问到spr ...

随机推荐

  1. 在控制台程序中,添加config文件

    一.右击类库 → 添加 → 新建项 → 应用程序配置文件(或者选择一个XML文件,然后将名字改成XXX.config),内容如下: <?xml version="1.0" e ...

  2. EBS 页面影藏“个性化页”

    以R12.1.3为例 影藏“个性化页”的方法: 修改配置文件: 个性化自助定义        值 由“是”改成“否” 注:修改之后需要清一下高速缓存,如果要显示“个性化页”则做相反配置 修改前: 修改 ...

  3. Java-Thread 线程

    一.进程与线程的概念 进程和线程都是一个CPU工作时间段的描述,只是关注点不同. 进程(Process): 资源(CPU,内存等,文件,网络等)分配的基本单位.系统中有很多进程,它们都会使用内存.为了 ...

  4. 学习笔记 - Git

    学习参考网址:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 Git是目前世界上 ...

  5. web开发(一)-Servlet详解

    在网上看见一篇不错的文章,写的详细. 以下内容引用那篇博文.转载于<http://www.cnblogs.com/whgk/p/6399262.html>,在此仅供学习参考之用. 一.什么 ...

  6. OpenStack 2018 年终盘点

    目录 文章目录 目录 前言 OpenStack 一年来的成长 Nova Cinder Neutron Ironic Cyborg Octavia Kolla Magnum Zun Kuryr 从 Op ...

  7. vue中关于checkbox数据绑定v-model指令的个人理解

    vue.js为开发者提供了很多便利的指令,其中v-model用于表单的数据绑定很常见, 下面是最常见的例子: <div id='myApp'>     <input type=&qu ...

  8. Python学习之==>迭代器

    一.概要 在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set ...

  9. [转] JavaScript学习:BOM和DOM的区别和关联

    BOM 1.  BOM是Browser Object Model的缩写,即浏览器对象模型. 2.  BOM没有相关标准. 3.  BOM的最根本对象是window. 从1可以看出来:BOM和浏览器关系 ...

  10. c++ 函数后面有个 const

    非静态成员函数后面加const,类似如下函数: class testClass{ public: void testClass() const{ /*...*/} private: /*...*/ } ...