Filter过滤器
【1】概念
Web过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能
过滤器的作用:
一般用于完成通用的操作,如:
登录验证(因为有些数据必须经过登录才能看见,可以通过过滤器将请求拦截下来判断)
统一编码处理
敏感字符过滤
........
【2】简单Filter过滤器入门
1) 步骤:
1. 定义一个类,实现接口Filter接口(注意导入javax.servlet.Filter)
2. 复写方法
3. 配置拦截路径有两种方法:1. 配置web.xml ,2. 注解配置
2) 代码:
//访问所有资源之前,都会执行该过滤器
@WebFilter("/*")//注解配置
public class FilterDome implements Filter{
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,FilterChain filterChain) throws IOException, ServletException {
System.out.println("FilterDome被执行了");
//放行
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
【3】过滤器细节
1) web.xml配置
<filter>
<filter-name>FilterDome</filter-name>
<filter-class>com.shao.filter.FilterDome</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDome</filter-name>
<!-- 拦截路径 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
2) 过滤器执行流程
1. 执行过滤器
2. 执行放行后的资源
3. 回来执行过滤器放行代码下边的代码
(就是要经过过滤器两次,请求时经过过滤器,被放行,响应时也需要经过过滤器)
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
//对request对象信息增强
System.out.println("FilterDome被执行了");
//放行
filterChain.doFilter(servletRequest, servletResponse);
//对response对象的响应信息增强
System.out.println("FilterDome又回来了");
}
3) 过滤器生命周期方法
1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
2. doFilter:每一次请求被拦截资源时,会执行。执行多次
3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
4) 过滤器配置详解
拦截路径配置:
1. 具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
2. 拦截目录: /user/* 访问/user下的所有资源时,过滤器都会被执行
3. 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
4. 拦截所有资源:/* 访问所有资源时,过滤器都会被执行
拦截方式配置:资源被访问的方式
注解配置:
设置dispatcherTypes属性
1. REQUEST:默认值。浏览器直接请求资源
2. FORWARD:转发访问资源
3. INCLUDE:包含访问资源
4. ERROR:错误跳转资源
5. ASYNC:异步访问资源
//浏览器直接请求index.jsp资源时,该过滤器才会被执行
@WebFilter(value="index.jsp",dispatcherTypes=DispatcherType.REQUEST)
//只有转发访问index.jsp时,该过滤器才会被执行
@WebFilter(value="index.jsp",dispatcherTypes=DispatcherType.FORWARD)
//浏览器直接请求index.jsp或者转发访问index.jsp,该过滤器才会被执行
@WebFilter(value="index.jsp",dispatcherTypes=
{DispatcherType.FORWARD,DispatcherType.REQUEST})
web.xml配置
设置<dispatcher></dispatcher>标签即可
5)过滤器链(配置多个过滤器)
1】执行顺序:如果有两个过滤器:过滤器1和过滤器2
过滤器1-->过滤器2-->资源执行-->过滤器2-->过滤器1
2】过滤器先后顺序问题:
1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
* 如: AFilter 和 BFilter,AFilter就先执行了。
2. web.xml配置: <filter-mapping>谁定义在上边,谁先执行
【4】案例:
需求:
- 判断是否是登录相关的资源(登录页面、验证码...)
是:直接放行
不是:判断是否登录
2,判断当前用户是否登录。判断Session中是否有User
如果登录了,则直接放行。
如果没有登录,则跳转到登录页面,提示"您尚未登录,请先登录"。
@WebFilter("/*")
public class LoginFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain fc) throws IOException, ServletException {
//【1】一般是基于HTTP协议在访问,只有在HTTP才有相关的请求与响应信息
//强制转换
HttpServletRequest request=(HttpServletRequest)req;
//【2】获取资源请求路径
String uri=request.getRequestURI();
//【3】判断是否包含登录相关资源路径(判断用户是否想登录)
//1)注意排除css/js/图片/验证码等资源,否则样式变乱,图片无法显示
if(uri.contains("/jsp/login.jsp")||uri.contains("/web/LoginServlet")||uri.contains("/Content/")
||uri.contains("/web/CheckCodeServlet")||uri.contains("/web/RegisterServlet")
||uri.contains("/jsp/register.jsp")){
//2)包含:用户就是想登录--放行
fc.doFilter(req, res);
}else{
//3)不包含,需要验证用户是否登录
//从session中获取User
Object user=request.getSession().getAttribute("sessionuser");
if(user!=null){
//4)登录便放行
fc.doFilter(req, res);
}else {
//5)没有登录。跳转登录页面
request.setAttribute("login_msg", "你尚未登录,请登录");
request.getRequestDispatcher("/jsp/login.jsp").forward(request, res);
}
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}