1、概述:
Filter是sun公司中servlet2.3后增加的一个新功能.
Servlet规范中三个技术 Servlet Listener Filter
在javaEE中定义了一个接口 javax.servlet.Filter来描述过滤器
通过Filter可以拦截访问web资源的请求与响应操作.
WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
过滤器是以一种组件的形式绑定到WEB应用程序当中的,与其他的WEB应用程序组件不同的是,过滤器是采用了“链”的方式进行处理的。
2、Filter API介绍
Filter是javax.servlet包下的一个接口主要有以下三个方法
3、Filter创建步骤:
1.创建一个类实现javax.servlet.Filter接口
2.得写接口方法
3.在web.xml文件中配置Filter
Filter在web.xml文件中配置的目的:
1.配置拦截什么样的资源。
2.Filter初始化
Filter配置方式:
方式一:
注解配置
@WebFilter(filterName="",urlPatterns={"/images/*"},
initParams={
@WebInitParam(name="fruit",value="grape")
})
方式二:
web.xml中配置
4、Filter拦截操作
注意:在Filter的doFilter方法内如果没有执行
那么资源是不会被访问到的。
5、FilterChain功能介绍
FilterChain 是 servlet 容器为开发人员提供的对象,它提供了对某一资源的已过滤请求调用链的视图。过滤器使用 FilterChain 调用链中的下一个过滤器,如果调用的过滤器是链中的最后一个过滤器,则调用链末尾的资源。
6、Filter链与Filter生命周期
1) Filter链介绍
多个Filter对同一个资源进行了拦截,那么当我们在开始的Filter中执行
chain.doFilter(request,response)时,是访问下一下Filter,直到最后一个Filter执行
时,它后面没有了Filter,才会访问web资源。
Ø 关于多个FIlter的访问顺序问题
如果有多个Filter形成了Filter链,那么它们的执行顺序是怎样确定的?
它们的执行顺序取决于
初始化时按着
2) Filter生命周期
当服务器启动,会创建Filter对象,并调用init方法,只调用一次.
当访问资源时,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法,
这个方法是真正拦截操作的方法.
当服务器关闭时,会调用Filter的destroy方法来进行销毁操作.
7、FileterConfig 介绍
1)功能介绍
在Filter中的init方法上有一个参数叫FilterConfig
FilterConfig是Filter的配置对象
它的作用:
1.获取Filter的名称
2.获取初始化参数
3.获取ServletContext对象
2)常用API
3)
8、Filter配置详解
1.完全匹配
要求必须以"/"开始.
2.目录匹配
要求必须以"/"开始,以*结束.
3.扩展名匹配
不能以"/"开始,以*.xxx结束.
针对于servlet拦截的配置
在Filter中它的配置项上有一个标签
是通过servlet的name来确定的。
可以取的值有 REQUEST FORWARD ERROR INCLUDE
它的作用是:当以什么方式去访问web资源时,进行拦截操作.
1.REQUEST 当是从浏览器直接访问资源,或是重定向到某个资源时进行拦截方式配置的 它也是默认值
2.FORWARD 它描述的是请求转发的拦截方式配置
3.ERROR 如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
4.INCLUDE 如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用
9、代码示例
定义编码过滤器:
public class EncodingFilter implements Filter{
private String encode;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("EncodingFilter初始化了...");
this.encode=filterConfig.getInitParameter("encode");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("进入EncodingFilter的doFilter...");
request.setCharacterEncoding(encode); // 设置请求编码
chain.doFilter(request, response);// “放行”
System.out.println("将要离开EncodingFilter的doFilter...");
}
@Override
public void destroy() {
System.out.println("EncodingFilter销毁了...");
}
}
定义登陆过滤器
package org.afanti.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("LoginFilter初始化了...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("进入LoginFilter的doFilter...");
HttpServletRequest req=(HttpServletRequest)request;
HttpSession session=req.getSession();
if(session.getAttribute("user")!=null){ // 如果session范围中user属性不为null,则说明已经登录
chain.doFilter(request, response); // “放行”
}else{
// String contextPath=request.getServletContext().getContextPath();
request.setAttribute("msg","您还未登录,请先登录!");
request.getRequestDispatcher("/login/login.jsp").forward(request, response); // 服务端跳转(转发)
// HttpServletResponse resp=(HttpServletResponse)response;
//resp.sendRedirect("/FilterProject/login/login.jsp");
}
System.out.println("将要离开LoginFilter的doFilter......");
}
@Override
public void destroy() {
}
}
登陆servlet编写
package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet(name="LoginServlet",urlPatterns={"/loginServlet"})
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String loginName=req.getParameter("loginName");
String loginPwd=req.getParameter("loginPwd");
if("tom".equals(loginName) && "123456".equals(loginPwd)){
req.getSession().setAttribute("user",loginName); // 如果登录成功,则先设置session范围的user属性
req.getRequestDispatcher("/success/welcome.jsp").forward(req, resp);
}else{
req.setAttribute("msg","用户名或密码错误,请重新输入!");
req.getRequestDispatcher("/login/login.jsp").forward(req, resp);
}
}
}
登陆JSP界面代码
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
1、监听器(Listener)概述
在WEB中可以对application、session、request三种操作进行监听。
Servlet监听器分为三种:
1.ServletContext监听器(容器监听器)
2.HttpSession监听器(会话监听器)
3.ServletRequest监听器(请求监听器)
2、监听器介绍:
Javaweb中的监听器是用于监听web常见对象HttpServletRequest,HttpSession,ServletContext
1.事件----一件事情
2.事件源---产生这件事情的源头
3.注册监听---将监听器与事件绑定,当事件产生时,监听器可以知道,并进行处理。
4.监听器---对某件事情进行处理监听的一个对象
3、Servlet监听器的配置方式
方式一:
注解配置: @WebListener
方式二:
web.xml中配置:
4、HttpSession监听器(对会话进行监听)
1).对会话状态(生命周期)进行监听
实现HttpSessionListener接口,覆写相关方法
2).对会话(HttpSession)属性范围进行监听
实现HttpSessionAttributeListener接口,覆写相关方法
3).对会话(HttpSession)属性范围进行监听———使用HttpSessionBindingListener接口
实现HttpSessionBindingListener接口,覆写相关方法
特别注意:使用HttpSessionBindingListener接口实现会话属性监听时,不用注册!
实现了HttpSessionBindingListener接口的类,将该类的对象在会话属性范围绑定和解绑属性时,会自动调用valueBound(xxx)方法和valueUnbound(xxx)方法。
5、ServletRequest监听器(请求监听器)
1.对请求状态(生命周期)进行监听
实现ServletRequestListener接口,覆写相关方法
2.对请求范围的属性进行监听
实现ServletRequestAttributeListener接口,覆写相关方法
6、代码示例: