目录

过滤器 filter

监听器 Listener


过滤器 Filter

设计执行流程:

1. 用户访问服务器
2. 过滤器 对Servlet请求进行拦截
3. 先进入过滤器, 过滤器处理
4. 过滤器处理完后再放行, 此时请求到达Servlet/JSP
5. Servlet处理
6. Servlet处理完后,再回到过滤器, 最后在由tomcat服务器相应用户;

就像一道门,进出都要经过


Javax.servlet.*;
|-- interface Filter   过滤器接口

开发一个普通java类,实现Filter接口,进行配置
 


Api

|-- interface Filter          过滤器核心接口

Void init(filterConfig);        初始化方法,在服务器启动时候执行

Void doFilter(ServletRequest,ServletResponse,filterChain);        过滤器拦截的业务处理方法

Void destroy();        销毁过滤器实例时候调用

|-- interface FilterConfig          获取在web.xml中配置的初始化参数信息

String getInitParameter(String name)         根据名称获取值

Enumeration getInitParameterNames()         获取所以参数名称

|-- interface FilterChain          过滤器链参数;一个个过滤器形成一个执行链;

void doFilter(ServletRequest request, ServletResponse response) ;        执行下一个过滤器或放行


 

web.xml配置:

<filter>
    <filter-name>hello_filter</filter-name>
    <filter-class>filter.hello_filter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hello_filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-name>hello_filter</filter-name>     filter内部名称

<url-pattern>对指定的请求拦截:

1.  拦截所有的请求

<url-pattern>/*</url-pattern>

2.   拦截所有的jsp

<url-pattern>*.jsp</url-pattern>

3.   拦截指定的servlet

<url-pattern>/index</url-pattern>

4.   根据servlet的内部名称拦截

<servlet-name>IndexServlet</servlet-name>

dispatcher拦截的类型:

默认拦截的类型   (直接访问或者重定向)

<dispatcher>REQUEST</dispatcher>

拦截转发

<dispatcher>FORWARD</dispatcher>

拦截包含的页面   (RequestDispatcher.include(/page.jsp); 对page.jsp也执行拦截)

<dispatcher>INCLUDE</dispatcher>

拦截声明式异常信息

<dispatcher>ERROR</dispatcher>

 


RationRose时序图:2个过滤器的执行流程

<!-- web.xml中过滤器配置 -->
	<filter>
		<!-- 配置初始化参数 -->
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>path</param-name>
			<param-value>c:/...</param-value>
		</init-param>
	
		<!-- 内部名称 -->
		<filter-name>hello_filter</filter-name>
		<!-- 过滤器类的全名 -->
		<filter-class>cn.itcast.a_filter_hello.HelloFilter</filter-class>
	</filter>
	<filter-mapping>
		<!-- filter内部名称 -->
		<filter-name>hello_filter</filter-name>
		<!-- 拦截所有资源 -->
		<url-pattern>/*</url-pattern>
	</filter-mapping>

 

/**
 * 过滤器,测试
 */
public class HelloFilter implements Filter{
	
	// 创建实例
	public HelloFilter(){
		System.out.println("1. 创建过滤器实例");
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("2. 执行过滤器初始化方法");
		
		// 获取过滤器在web.xml中配置的初始化参数
		String encoding = filterConfig.getInitParameter("encoding");
		System.out.println(encoding);
		
		// 获取过滤器在web.xml中配置的初始化参数 的名称
		Enumeration enums =  filterConfig.getInitParameterNames();
		while (enums.hasMoreElements()){
			// 获取所有参数名称:encoding、path
			String name = enums.nextElement();
			// 获取名称对应的值
			String value = filterConfig.getInitParameter(name);
			System.out.println(name + "\t" + value);
		}
	}

	// 过滤器业务处理方法: 在请求到达servlet之前先进入此方法处理公用的业务逻辑操作
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("3. 执行过滤器业务处理方法");

		// 放行 (去到Servlet)
		// 如果有下一个过滤器,进入下一个过滤器,否则就执行访问servlet
		chain.doFilter(request, response);
		
		System.out.println("5. Servlet处理完成,又回到过滤器");
	}

	@Override
	public void destroy() {
		System.out.println("6. 销毁过滤器实例");
	}

}
 enums =  filterConfig.getInitParameterNames();
		while (enums.hasMoreElements()){
			// 获取所有参数名称:encoding、path
			String name = enums.nextElement();
			// 获取名称对应的值
			String value = filterConfig.getInitParameter(name);
			System.out.println(name + "\t" + value);
		}
	}

	// 过滤器业务处理方法: 在请求到达servlet之前先进入此方法处理公用的业务逻辑操作
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("3. 执行过滤器业务处理方法");

		// 放行 (去到Servlet)
		// 如果有下一个过滤器,进入下一个过滤器,否则就执行访问servlet
		chain.doFilter(request, response);
		
		System.out.println("5. Servlet处理完成,又回到过滤器");
	}

	@Override
	public void destroy() {
		System.out.println("6. 销毁过滤器实例");
	}

}

 

常用案例:

1.编码 在开发中:工作区间编码、项目编码、request/response、数据库编码一致!

     几乎每一个Servlet都要涉及编码处理:处理请求数据中文问题!(GET/POST)每个servlet都要做这些操作,把公用的代码抽取用过滤器实现!

2.无效数据过滤,论坛过滤敏感词汇

3.登陆权限判断

 


监听器 Listener

Listener 的作用: 是用于监听 web应用的创建和销毁
web应用即ServletContext对象(jsp的隐式对象application) 
还能监听sessionrequest的生命周期,以及他们的attribute发生的变化。

是一个实现特定接口的普通java类!
对象:

自己创建自己用 (不用监听)

别人创建自己用 (需要监听)

Servlet中需要监听的对象: servletContext request session
分别对应的是:request监听器、session相关监听器、servletContext监听器


监听器开发步骤:

1. 写一个普通java类,实现相关接口;

2. 配置(web.xml)

监听器接口
一、监听对象创建 / 销毁的监听器接口

Interface ServletRequestListener          监听request对象的创建或销毁

Interface HttpSessionListener          监听session对象的创建或销毁

Interface ServletContextListener          监听servletContext对象的创建或销毁

二、监听对象属性的变化

Interface ServletRequestAttributeListener          监听request对象属性变化: 添加、移除、修改

Interface HttpSessionAttributeListener          监听session对象属性变化: 添加、移除、修改

Interface ServletContextAttributeListener         监听servletContext对象属性变化

三、session相关监听器

Interface HttpSessionBindingListener          监听对象绑定到session上的事件

Interface HttpSessionActivationListener         (了解) 监听session序列化及反序列化的事件


生命周期监听器

监听对象的创建、销毁的过程!

1.1 监听Context对象的创建或销毁

 

package listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ContextListener implements ServletContextListener {
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("web 应用销毁  ");
    }
 
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        System.out.println("web 应用初始化 ");
    }
}
<listener>
    <listener-class>listener.ContextListener</listener-class>
</listener>

1.2 监听Context对象属性变化

public class ContextAttributeListener implements ServletContextAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent e) {
        System.out.println("增加属性 ");
        System.out.println("属性是" + e.getName());
        System.out.println("值是" + e.getValue());
    }
 
    @Override
    public void attributeRemoved(ServletContextAttributeEvent e) {
        // TODO Auto-generated method stub
        System.out.println("移除属性 ");
    }
 
    @Override
    public void attributeReplaced(ServletContextAttributeEvent e) {
        // TODO Auto-generated method stub
        System.out.println("替换属性");
    }
}
<listener>
    <listener-class>listener.ContextAttributeListener</listener-class>
</listener>


2.1  监听session对象的创建或销毁

 

 

 

 

 

 

 

 

2.2  监听session对象属性变化

 

 

3.1  监听request对象的创建或销毁

 

 

3.2  监听request对象属性变化

 

 

案例:借助SESSION监听器统计当前在线人数

 


 

国际化

国际化又简称为 i18n:internationalization

如何做到国际化的软件,要求:

1. 软件中存储特定的字符串

2. 知道浏览器当前使用哪种语言(Locale )

Locale 本地化
Java提供了一个本地化的对象!封装当前语言、国家、环境等特征

 

国际化

静态数据国际化

动态文本国际化

Jsp页面国际化

Jsp页面国际化 – 使用jstl标签

 

 

 

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐