过滤器
过滤器(拦截器)
1.什么是过滤器?
过滤器可以对访问web资源的请求或响应进行拦截
2.过滤器的生命周期?
与servlet类似,要想让过滤器生效,不仅要实现package javax.servlet接口,而且要在web.xml中进行配置,配置方法与servlet类似
3.过滤器中的方法?
-init():在servlet容器启动时执行
-destroy():在servlet容器关闭时执行
-doFilter():主要的方法,其中chain.doFilter()方法是放行
4.执行原理:
如上图所示,当客户端login.jsp访问服务端success.jsp资源时,过滤器会在客户端请求时拦截该请求,当执行完过滤器doFilter()方法后(放行),请求到达服务端且请求结束,服务端将响应发送给客户端的途中第二次被过滤器拦截,因为在过滤器中编写类doFilter()方法,所以响应被放行,接着到达客户端。
5.(重点)过滤器什么时候会起作用?(不配置dispatcher属性)
-直接通过超链接或是地址栏的方式访问被过滤器拦截的资源
-重定向方式跳转到被过滤器拦截的资源
6.关于dispatcher属性与通配符
<!--配置过滤器
<filter>
<filter-name>MyServlet</filter-name>
<filter-class>com.mamusha.filter.FilterTest</filter-class>
</filter>
<filter-mapping>
<filter-name>MyServlet</filter-name>
使用通配符进行拦截,拦截一切请求
<url-pattern>/*</url-pattern>
测试dispatcher属性
<url-pattern>/resource/dispatcher.html</url-pattern>
dispatcher属性常用值
-REQUEST:拦截http请求:get、post,不能拦截请求转发方式的请求
-FORWARD:只拦截通过请求转发方式的请求,不会拦截其它任何请求
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
过滤器链根据filter-mapping的先后确定执行顺序
<filter>
<filter-name>MyServlet2</filter-name>
<filter-class>com.mamusha.filter.FilterTest2</filter-class>
</filter>
<filter-mapping>
<filter-name>MyServlet2</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
-->
7.源码解释:
import javax.servlet.*;
import java.io.IOException;
/**
* 过滤器(拦截器)
* 1.什么是过滤器?
* 过滤器可以对访问web资源的请求或响应进行拦截
* 2.一个普通的java类想要变得具备特定的功能,要么继承一个类;要么实现一个接口;要么添加注解
* 3.过滤器的生命周期与servlet类似
* 4.要想让过滤器生效,不仅要实现package javax.servlet接口,而且要在web.xml中进行配置,配置方法与servlet类似
*/
public class FilterTest implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化,在服务器启动的时候自动调用init方法,且只执行一次
System.out.println("Filter...init....");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
/**
* 过滤器的最重要的方法就是doFilter方法
* 当用户向客户端发送请求时,过滤器会进行一次拦截,当过滤器执行
*/
System.out.println("filter1...拦截请求...");
chain.doFilter(request,response);// 放行
System.out.println("filter1...拦截响应...");
}
@Override
public void destroy() {
// 销毁,关闭服务器时自动调用该方法,且只执行一次
System.out.println("Filter...destroy....");
}
}
监听器
对象监听器:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 监听器
* 1.监听对象
* -request
* -session
* -appliction
*
* 2.可以实现的接口
* -ServeltContextListener
* -ServeltAttributeContextListener
* -HttpSessionListener
* -HttpAttributeSessionListener
* -ServletRequestListener
* -ServletAttributeRequestListener
*
* 3.实现监听器的步骤
* 1)创建一个java类实现ServletContextListener、ServletRequestListener、HttpSessionListener接口
* 2)配置web.xml文件中的映射关系<listener></listener>
*/
public class ListenerTest implements ServletContextListener, ServletRequestListener, HttpSessionListener {
// 监听appliction对象
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
// 初始化,服务器启动时执行
System.out.println("创建ServletContext对象...");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
// 销毁,在服务器关闭时执行
System.out.println("销毁ServletContext对象...");
}
// 监听request对象
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
// 发出请求时执行
System.out.println("创建request对象...");
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
// 请求结束时执行
System.out.println("销毁request对象...");
}
// 监听session对象
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
// 第一次访问服务器时执行
System.out.println("创建session对象...");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
// 调用session.invalidate()方法时执行
System.out.println("销毁session对象...");
}
}
属性监听器:
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
/**
1. 属性监听器
2. 1.监听哪些属性
3. 通用方法:ServletContextAttributeListener、ServletRequesAttributetListener、HttpSessionAttributeListener对象
4. -attributeAdded():增加属性
5. -attributeRemoved():删除属性
6. -attributeReplaced():修改属性
*/
public class ListenerAttributeTest implements ServletContextAttributeListener, ServletRequestAttributeListener, HttpSessionAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
// 获取新增属性名
String name = servletContextAttributeEvent.getName();
System.out.println("ServletContext对象新增"+name+"属性");
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
// 获取删除属性名
String name = servletContextAttributeEvent.getName();
System.out.println("ServletContext对象删除"+name+"属性");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
// 获取修改属性名
String name = servletContextAttributeEvent.getName();
System.out.println("ServletContext对象修改"+name+"属性");
}
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
// 获取新增属性名
String name = servletRequestAttributeEvent.getName();
System.out.println("servletRequestAttributeEvent新增"+name+"属性");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
// 获取删除属性名
String name = servletRequestAttributeEvent.getName();
System.out.println("servletRequestAttributeEvent删除"+name+"属性");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
// 获取修改属性名
String name = servletRequestAttributeEvent.getName();
System.out.println("servletRequestAttributeEvent修改"+name+"属性");
}
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
// 获取新增属性名
String name = httpSessionBindingEvent.getName();
System.out.println("httpSessionBindingEvent新增"+name+"属性");
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
// 获取删除属性名
String name = httpSessionBindingEvent.getName();
System.out.println("httpSessionBindingEvent删除"+name+"属性");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
// 获取修改属性名
String name = httpSessionBindingEvent.getName();
System.out.println("httpSessionBindingEvent修改"+name+"属性");
}
}
重点:关于对象监听器什么执行分析:
ServeltContextListener:
当Servlet容器启动时执行contextInitialized()方法,当Servlet容器关闭时执行contextDestroyed()方法
ServletRequestListener:
当客户端请求服务端时执行requestInitialized()方法,当请求结束时(即请求到达服务端)时执行requestDestroyed()方法
HttpSessionListener:
当客户端第一次访问服务端时执行sessionCreated()方法,当用户退出登陆或者是调用session.invalidate()方法时执行sessionDestroyed()方法