目录
1、概念
过滤器(Filter)是处于客户端与服务器目标资源之间的一道过滤技术。
2、过滤器作用
执行顺序在Servlet之前,客户端发送请求时,会先经过Filter,再到达目标Servlet中;响应时,会根据执行流程再次反向执行Filter
可以解决多个Servlet共性代码的冗余问题(例如:乱码处理、登录验证)
3、编写过滤器
Servlet API中提供了一个
Filter接口
,开发人员编写一个Java类实现了这个接口
即可,这个Java类称之为过滤器(Filter)
编写Java类实现Filter接口
在
doFilter方法
中编写拦截逻辑设置拦截路径@WebFilter("path"),path写法
/* 拦截所有请求路径
/a 拦截指定的/a请求
*.do 拦截指定的后缀请求
也可以写对多个 {"/a","/b"}
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//@WebFilter("/TestServlet1")//去拦截TestServlet1这个资源 精准拦截
//@WebFilter("/*")//全部拦截资源
// @WebFilter("*.html")//不要写/ 拦截后缀是 html的
public class FilterTest1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 核心方法
* @param servletRequest
* @param servletResponse
* @param filterChain (l连接器链 可以配置多个拦截器)
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//放行代码, 如果不写则拦截 重要的代码!!!
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("FilterTest1....end");
}
@Override
public void destroy() {
}
}
4 过滤器链和优先级
4.1 过滤器链
客户端对服务器请求之后,服务器调用Servlet之前会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。
每个过滤器实现某个特定的功能,当第一个Filter的doFilter方法被调用时,Web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则Web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。
2 过滤器优先级
在一个Web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。 优先级:
如果为注解的话,是按照类全名称的字符串顺序决定作用顺序
5、过滤器应用:全局编码加身份认证拦截器
使用拦截器,对所有请求拦截器,设置编码,然后放行
使用拦截
import com.qf.model.EmpManager; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebFilter("/*") public class LoginFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //获取session //getSession方法 是 HttpServletRequest HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletResponse resp = (HttpServletResponse) servletResponse; HttpSession session = req.getSession(); String requestURI = req.getRequestURI(); localhost:8080/login.html 打印的是login.html //localhost:8080/IndexServet 打印的是IndexServet //localhost:8080/login 打印的是login System.out.println(requestURI); /** * 因为是拦截所有 /* * 所以要放行 静态资源以及第一次登录的请求 */ if(requestURI.contains("login")) { //把login.html /login资源 filterChain.doFilter(servletRequest, servletResponse);// } else { //从session中获取数据 EmpManager empManager= (EmpManager)session.getAttribute("empManager"); //判断 if(empManager != null) { filterChain.doFilter(servletRequest, servletResponse);// } else { resp.sendRedirect("login.html"); } } } @Override public void destroy() { } }
器,将身份过滤的代码前置到拦截器,对每个请求先身份认证