Filter(过滤器)
作用:
一般用于完成通用的操作。如:登录验证,统一编码处理,敏感字符过滤…
Filter细节
-
web.xml配置
<filter> //给filter文件起的别名 <filter-name>loginFilter</filter-name> //filter文件的位置 <filter-class>com.lijihan.www.web.filter.LoginFilter</filter-class> </filter> //filter映射 <filter-mapping> //给filter起的别名 <filter-name>loginFilter</filter-name> //filter文件的作用范围(下面会详解) <url-pattern>/*</url-pattern> </filter-mapping>
-
过滤器执行流程
- 执行过滤器
- 执行放行后的资源
- 回来执行过滤器放行代码下边的代码
-
过滤器生命周期方法
- init:在服务器启动后,会创建Filter对象,然后调用init方法,只执行一次。用于加载资源。
- doFilter:每一次请求被拦截资源时,会执行。执行多次。
- destory:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destory方法,只执行一次。用于释放资源
-
过滤器配置详解
-
拦截路径配置:
- 具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行
- 拦截目录:/user/* 访问/user下的所有资源时,过滤器都会被执行
- 后缀名拦截:*.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
- 拦截所有资源:/* 访问所有资源时,过滤器都会被执行
-
拦截方式配置:资源被 访问的方式
-
注解配置:(通过注解可以替代web.xml的配置)
@WebFilter(value = "/*",dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST})
设置dispatcherTypes属性
- REQUEST:默认值,浏览器直接请求资源
- FORWORD:转发访问资源
- INCLUDE:包含访问资源(在jsp学习中会了解)
- ERROR:错误跳转资源(在jsp学习中会了解)
- ASYNC:异步访问资源
-
web.xml配置
<filter> <filter-name>loginFilter</filter-name> <filter-class>com.lijihan.www.web.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping>
-
-
-
过滤器链(如果配置了多个Filter,执行顺序)
-
执行顺序:如果有两个过滤器,过滤器1和过滤器2
- 过滤器1
- 过滤器2
- 资源执行
- 过滤器2
- 过滤器1
-
过滤器先后顺序问题
-
注解配置:按照类名的字符串比较规则比较,值小的先执行
如:AFilter和BFilter,AFilter就先执行了
-
web.xml配置:谁定义在上边,谁先执行
-
-
案例:
介绍:
在用户没有登录的情况下用户不能访问服务器中的资源
代码实现与讲解
package com.lijihan.www.web.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
//采用注解的方法来说明Filter的作用范围,DispatcherType默认为REQUEST
@WebFilter(value="/*")
public class LoginFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//先转为httpServletRequest,httpServletRequest为ServletRequest的子类
HttpServletRequest request = (HttpServletRequest) req;
//获取请求者的URI地址
String requestURI = request.getRequestURI();
//如果是以下的当然得放行了,因为,checkCodeServlet是login.jsp中的验证码,login.jsp是登录页面,loginServlet是进行登录时的代码,而js/css/fonts是login.jsp页面中需要的前端代码当然也不能拦截
if (requestURI.contains("/login.jsp") || requestURI.contains("/css") || requestURI.contains("/js") || requestURI.contains("/checkCodeServlet") || requestURI.contains("/fonts") || requestURI.contains("/loginServlet")){
//是上面那些就放行
chain.doFilter(req, resp);
}else{
//通过判断是否用username属性值来判断用户是否已经登录
String userName = (String)request.getSession().getAttribute("username");
if (userName != null) {
//不为null说明已经登录了,放行
chain.doFilter(req,resp);
}else{
//看来没有登录,就重新回到login.jsp页面中
//通过request作用域来设置,没登录成功的原因
request.setAttribute("login_message","您尚未登录请登录");
//实现转发
request.getRequestDispatcher("/login.jsp").forward(request,resp);
}
}
}
public void init(FilterConfig config) throws ServletException {
}
}