过滤器:
定义:是一个服务器端的组件,它可以截取用户端的请求与响应信息,并对这些信息过滤
工作原理:
生命周期:
实例化,通过配置web.xml,web容器启动的时候只会实例化一次
初始化,init(),加载初始化信息,只执行一次。
这个是过滤器的初始化方法,web容器创建过滤器实例后悔调用这个方法。这个方法中可以读取web.xml文件中过滤器的参数
过滤,doFiter(),执行n次
这个方法完成实际的过滤操作,这个地方是过滤器的核心方法,当用户请求访问与过滤器关联的url时,web容器将先调用过滤器的doFilter方法。
FilterChain参数可以调用chain.doFilter方法,将请求传给下一个过滤器,或者目标资源,或利用转发,重定向将请求转发到其他资源。
销毁,destory(),web容器关闭的时候回销毁
web容器在销毁过滤器实例前调用该方法,在这个方法中可以释放过滤器占用的资源(大多数情况用不到)。
过滤器链:
用户请求先执行过滤器1的doFilter中的Code1方法(放行前的方法),再执行Chain.doFilter方法,再执行过滤器2中的doFilter中的Code1方法,再执行Chain.doFilter方法,到达web资源,也就是Servler的serbice方法。处理完响应后,把处理后的响应数据首先反馈给过滤器2的Code2(放行方法后的方法),再反馈给过滤器1的Code2方法,最后响应给用户。
过滤器分几种类型:
Servler2.5
REQUEST:
用户直接访问页面时,web容器将会调用过滤器
FORWARD:目标资源是通过requestDispatcher的forward方法访问时,该过滤器将会被调用
INCLUDE:目标资源是通过requestDispatcher的inclued方法访问时,该过滤
器将会被调用
ERROR:目标资源是通过声明式异常处理机制调用时,该过滤器将会被调用
Servler3.0 新增ASYNC:支持异步处理
@WebFilter
Springboot中配置过滤器步骤:
方法一:
1.新建myFilter类,实现Filter接口(javax.servler下的)
实现init(),doFilter(),desory()
2.在myFilter类上添加注解,@WebFilter, urlPatterns = {"/test/hello"}
注意:test是HelloController的映射路径,hello是HelloController下的一个测试方法。
package com.example.guoq.CommonUtils;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(filterName = "myFilter",urlPatterns = {"/test/hello"})
public class myFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println(">>init>>>>>>>>>>>>");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println(">>start>>>>>>>doFilter>>>>>");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println(">>end>>>>>>>doFilter>>>>>");
}
@Override
public void destroy() {
System.out.println(">>>>>destory>>>>>>>>>>>>>>>>");
}
}
3.在springboot启动类上添加@ServletComponentScan注解,启动
这个时候,控制台会打印init这个方法,然后执行test下的hello方法会打印doFilter中的代码。
注:如果没有在启动类上添加注解@ServletComponentScan,而是在myFiler添加注解Component,这个时候会过滤所有的路径(亲测)。
package com.example.guoq;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
------------
package com.example.guoq.controller;
import com.example.guoq.CommonUtils.ShareRunable;
import com.example.guoq.CommonUtils.SimpleCached;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class HelloController {
SimpleCached simpleCached=new SimpleCached();
@RequestMapping("/hello")
public String index(){
return "hello world";
}
}
---------------
方法二:
1.新增一个FilterConfiger类,该类添加@Configuration和@Bean注解,如下,
addUrlPatterns添加过滤的路径,test是HelloController的映射
package com.example.guoq.config;
import com.example.guoq.CommonUtils.myFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean();
filterRegistrationBean.setFilter(new myFilter());
filterRegistrationBean.addUrlPatterns("/test/hello");
return filterRegistrationBean;
}
}
2.新增myFilter类,实现Filter,不添加任何注解
package com.example.guoq.CommonUtils;
import javax.servlet.*;
import java.io.IOException;
public class myFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println(">>init>>>>>>>>>>>>");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println(">>start>>>>>>>doFilter>>>>>");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println(">>end>>>>>>>doFilter>>>>>");
}
@Override
public void destroy() {
System.out.println(">>>>>destory>>>>>>>>>>>>>>>>");
}
}
3.启动,执行test下的hello方法