一,过滤器
1.1 使用过滤器的步骤
第一步:定义一个类,继承Filter,重写doFilter方法。
package com.chinasofti.day11.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;
/*
过滤器
*/
public class MyFilter implements Filter {
// 创建过滤器时候自动调用。容器启动的时候创建过滤器。
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("执行MyFilter的init方法..");
}
// 每次请求Servlet时候,如果配置了过滤器,每次请求都会执行该方法
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("执行MyFilter的doFilter方法...");
}
// 过滤器被销毁时候自动执行
@Override
public void destroy() {
System.out.println("执行MyFilter的destroy方法...");
}
}
第二步:在web.xml中配置过滤器。
<!-- 配置过滤器 -->
<filter>
<!-- 过滤器的名字 -->
<filter-name>MyFilter</filter-name>
<!-- 过滤器的完整类名 -->
<filter-class>com.chinasofti.day11.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/hello</url-pattern>
</filter-mapping>
上面url-pattern配置过滤器的路径。当用户请求/hello的时候,首先会进入到,MyFilter过滤器中。只有当过滤器执行了放行操作的时候,才会执行目标Servlet。
1.2 FilterConfig
该对象用于获取Filter的配置参数。例如:
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("执行MyFilter的init方法..");
// 获取过滤器的配置参数
name = filterConfig.getInitParameter("name");
}
我们可以在filter节点中指定配置参数:
<!-- 配置参数 -->
<init-param>
<param-name>name</param-name>
<param-value>jacky</param-value>
</init-param>
1.3 过滤器链
如果在同一个资源上配置了多个过滤器,那么访问资源的时候,就会按照下面顺序执行过滤器中是代码:
先配置的过滤器就会先启动,然后再执行放行,最后按照配置顺序的相反方向执行放行后的代码。比如有两个Filter,一个FilterA,另外一个FilterB。FilterA先配置,所以执行顺序是:
-
执行FilterA放行前代码;
-
执行FilterA放行代码;
-
执行FilterB放行前代码;
-
执行FilterB放行代码;
-
执行目标Servlet;
-
执行FilterB放行后代码;
-
执行FilterA放行后代码
1.4 过滤器的应用场景
1))登记认证
2)项目全局中文乱码处理
3)七天免登陆
七天免登陆的过滤器演示:
package com.eight.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebFilter(value={"/index.html", "/admin/*"})
public class LoginFilter implements javax.servlet.Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) arg0;
HttpServletResponse resp = (HttpServletResponse) arg1;
//获取当前所有的cookie
Cookie[] cookies = req.getCookies();
/**
* 定义标志位,默认为false
* 若为true,就直接通过过滤器
*/
boolean mark = false;
if(cookies != null){
for (Cookie cookie : cookies) {
if("adminName".equals(cookie.getName())){
req.getSession().setAttribute("adminName", cookie.getValue());
mark = true;
}
}
}
if(mark){
//通过过滤器
arg2.doFilter(req, resp);
}else{
Object adminName = req.getSession().getAttribute("adminName");
if(adminName != null){
arg2.doFilter(req, resp);
}else{
resp.sendRedirect(req.getContextPath() + "/login.html");
}
}
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
二,监听器
监听器是JavaWeb三大组件之一。监听器可以监听一些对象或对象属性状态的变化。
2.1 监听器四要素
- 事件源:Web对象。例如:HTTPSession对象,ServletRequest对象,ServletContext对象。
- 事件类型:ServletContextEvent,ServletRequestEvent、HttpSessionEvent,ServletContextAttributeEvent,ServletRequestAttributeEvent,HttpSessionAttributeEvent。
- 事件监听器:ServletContextListener,ServletRequestListener、HttpSessionListener、ServletContextAttributeListener、ServletRequestAttributeListener、HttpSessionAttributeListener。
- 处理函数:监听器中的一些处理方法。
2.2 监听对象状态的监听器
ServletContextListener:监听Servlet对象状态的监听器。
HTTPSessionListener:监听Session对象状态的监听器。
ServletRequestListener:监听Request对象状态的监听器。
下面以ServletContextListener为例介绍:
ServletContextListener由于监听ServletContextListener对象状态的变化。例如:创建ServletContextListener,销毁ServletContext。当项目启动的时候,容器会创建ServletContextListener对象,如果配置了ServletContextListener监听器,那么久可以在项目启动的时候加入一些处理。
第一步:定义一类,实现监听器接口,
并实现监听器的所有方法:
/*
ServletContextListener
*/
public class MyServletContextListener implements ServletContextListener {
// 创建servletContext对象时候自动调用
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象被创建了..");
}
// ServletContext对象被销毁时候自动调用
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象被销毁了..");
}
}
第二步:在web.xml中配置监听器:
<!-- 配置监听器 -->
<listener>
<listener-class>com.chinasofti.day12.listener.MyServletContextListener</listener-class>
</listener>
2.3 监听对象属性状态的监听器
ServletContextAttributeListener:监听Servlet对象属性状态的监听器。
HttpSessionAttributeListener:监听Session对象属性状态的监听器。
ServletRequestAttributeListener:监听Request对象属性状态的监听器。
下面以ServletContextAttributeListener为例介绍:
ServletContextAttributeListener用于监听ServletContext对象属性状态的变化。例如:添加属性、删除属性、修改属性。
/*
监听ServletContext对象属性状态的变化
*/
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
// 往Servletcontext对象中添加属性的时候自动调用
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("attributeAdded...");
System.out.println("属性名:" + scae.getName());
System.out.println("属性值:" + scae.getValue());
}
// 往Servletcontext对象中删除属性的时候自动调用
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("attributeRemoved...");
System.out.println("删除的属性名:" + scae.getName());
System.out.println("删除前属性的值:" + scae.getValue());
}
// 往Servletcontext对象中修改属性的时候自动调用
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("attributeReplaced...");
System.out.println("修改前的值:" + scae.getValue());
System.out.println("修改后的值:" + scae.getServletContext().getAttribute("jdbcUrl"));
}
}
如果有多个监听器同时起作用,那么会按照它们在web.xml中定义的顺序来执行。