目录
MVC和三层架构模型的联系
Filter
概念
作用
应用场景
步骤
简单入门
注解开发
Filter过滤器的生命周期
Filter的拦截路径
过滤链
MVC和三层架构模型的联系
m-->model即模型是三层架构模型的业务层(service)和持久层(dao)
v-->views即视图是三层架构模型的表现层(web)
c-->controller即控制器也是三层架构模型的表现层(web)
Filter
概念
Filter表示过滤器属于java.servlet.Filter接口类型,过滤器可以对访问的静态和动态资源进行过滤,既可以过滤请求,也可以过滤响应
作用
1.拦截客户端对web资源的请求
web资源
静态:html,css,js,img
动态:jsp,servlet
2.拦截web资源对客户端的响应
应用场景
1.解决post请求中文乱码(全栈)
2.敏感字符过滤
3.登录权限进行校验
步骤
1.自定义类实现Filter接口
2.在实现类实现接口的所有代码
3.在doFilter方法中书写过滤资源的代码
4.在web.xml中配置过滤器
5.访问被过滤的资源
简单入门
//自定义类实现Filter接口 public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {//不要调用父类的方法,否则会报错//Filter.super.init(filterConfig);}//在doFilter中书写拦截资源的代码//每次访问被过滤的资源都要执行该方法@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("doFilter...");}@Overridepublic void destroy() {} }
在web.xml配置Filter
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0"><!-- 配置Filter--><filter><filter-name>MyFilter</filter-name><filter-class>com.hhh.filter.MyFilter</filter-class></filter> <!-- 配置的是当前过滤器过滤的资源路径,表示Myfilter过滤器过滤demo1.html的请求和响应--><filter-mapping><filter-name>MyFilter</filter-name><url-pattern>/demo1.html</url-pattern></filter-mapping> </web-app>
tomcat底层解析xml获取过滤类的全路径,使用反射技术调用Myfilter类中的无参构造方法创建对象,使用对象调用MyFilter类的doFilter方法
Class c=Class.forName("过滤类的全路径");
MyFilter f=c.newInstance();
f.doFilter(request,response);
前端代码
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><h1>我是被过滤的</h1> </body> </html>
浏览器:
可以发现不显示前端的内容,因为已经被过滤
但是在控制台有结果
该怎么查看被过滤的资源呢
在doFilter中书写放行代码
import javax.servlet.*; import java.io.IOException; //自定义类实现Filter接口 public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {//不要调用父类的方法,否则会报错//Filter.super.init(filterConfig);}//在doFilter中书写拦截资源的代码//每次访问被过滤的资源都要执行该方法@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("doFilter...");//放行filterChain.doFilter(servletRequest,servletResponse);}@Overridepublic void destroy() {}
结果
注解开发
@WebFilter("/demo2.html") public class myFilter1 implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {}@Overridepublic void destroy() {} }
Filter过滤器的生命周期
1.当启动tomcat服务器的时候tomcat会调用过滤器类的无参构造方法创建过滤器类的对象
(Servlet是第一次访问servler类才创建对象)
2.然后使用过滤器类的对象调用Init方法进行初始化
3.每次访问被过滤的资源都会调用doFiter方法 实际开发中我们在此方法处理被过滤的资源逻辑
4.关闭tomcat服务器之后,使用过滤器对象调用destroy方法
Filter的拦截路径
1.精准匹配
用户访问指定的目标资源(demo1.html)时,过滤器进行拦截
2.目录匹配
用户访问指定的目录时(/user/*)所有资源时 ,过滤器进行拦截
只要浏览器访问路径以user开头的资源就会执行当前过滤器
3.后缀匹配
用户访问指定的后缀名(*.html)所有资源时 ,过滤器进行拦截
只要浏览器访问路径以html结尾的资源就会执行当前过滤器
注意:这里不能加/
4.匹配所有
用户访问该网站的所有资源(/*),过滤器进行拦截
只要浏览器访问当前项目就会执行当前过滤器
在过滤器中,如果多个过滤器过滤同一个资源,那么就会执行所有过滤器
过滤链
就是多个过滤器过滤同一个资源时形成的一条链子
测试
servlet资源
@WebServlet("/servlet1") public class servlet1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("servlet");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);} }
过滤器
@WebFilter("/servlet1") public class Afilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//your code..System.out.println("Afilter过滤器前");//放行filterChain.doFilter(request,response);System.out.println("Afilter过滤器后");}@Overridepublic void destroy() {} }
@WebFilter("/servlet1") public class Bfilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//your code..System.out.println("Bfilter过滤器前");//放行filterChain.doFilter(request,response);System.out.println("Bfilter过滤器后");}@Overridepublic void destroy() {} }
在浏览器访问servlet1时
结果
Afilter过滤器前
Bfilter过滤器前
servlet
Bfilter过滤器后
Afilter过滤器后可以看出,当A过滤器执行filterChain.doFilter(request,response);放行代码后 才能到过滤器B,
B过滤器执行filterChain.doFilter(request,response);请求的数据才会到servlet1,然后servlet响应数据会浏览器时,也要经过两次过滤器
总结
1.前提条件:当多个多滤器在同一个包下过滤同一资源有以下规律(注解开发)
执行过滤器的顺序是过滤器类的字符升序
2.如果是xml配置方式,多个过滤器过滤同一个资源有以下规律
执行过滤器的顺序是在xml文件中出现的顺序