Filter
Java Web中的过滤器可以拦截所有访问Web资源的请求或响应操作并执行过滤任务。
生命周期
Filter生命周期:
- 当服务器启动,会创建Filter对象,并调用init方法,只调用一次。
- 当访问资源时,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法,这个方法是真正拦截操作的方法。
- 当服务器关闭时,会调用Filter的destroy方法来进行销毁操作。
FilterConfig
Filter的配置参数保存在其中,可以在初始化函数init()中传入。
FilterChain
多个Filter组成一个FilterChain,Filter的执行顺序和web.xml中的声明顺序一致。
实战
之前通过request.setCharacterEncoding("utf-8")和response.setCharacterEncoding("utf-8")来设置报文编码,每次都要设置,比较繁琐。这里我们添加一个Filter来统一设置编码。
编写Filter类。
package com.wyk.servletdemo.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyEncodingFilter implements Filter {
private String encoding;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter init...");
if(filterConfig != null && filterConfig.getInitParameter("encoding") != null
&& !filterConfig.getInitParameter("encoding").equals("")) {
encoding = filterConfig.getInitParameter("encoding");
} else {
encoding = "UTF-8";
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
// 拦截所有的请求 解决全站中文乱码
request.setCharacterEncoding(this.encoding);
response.setCharacterEncoding(this.encoding);
response.setContentType("text/html;charset=" + this.encoding);
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("Filter destroy...");
}
}
在web.xml中配置Filter。
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>com.wyk.servletdemo.filter.MyEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Listener
监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。
监听器主要由三部分构成:
- 事件源:被监听的对象
- 监听器:监听的对象,事件源的变化会触发监听器的响应行为
- 响应行为:监听器监听到事件源的状态变化时所执行的动作
监听器的执行流程如下:
- 给事件源注册监听器。
- 组件接受外部作用,也就是事件被触发。
- 组件产生一个相应的事件对象,并把此对象传递给与之关联的事件处理器。
- 事件处理器启动,并执行相关的代码来处理该事件。
看一个窗口监听器的例子。
public static void main(String[] args) {
// 创建窗口
Frame f = new Frame();
f.setSize(400, 400);
f.setTitle("Listener测试");
f.setVisible(true);
//创建事件监听器
f.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
Frame f = (Frame)e.getSource();
System.out.println(f + "窗口正在关闭");
f.dispose();
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
}
运行程序,关闭出现的窗口,可以监听到事件。
listener-demo.jpgWeb监听器
Java Web中的监听器是Servlet规范中定义的一种特殊类,它用于监听Web应用程序中的事件。
分类
Web监听器按照被监听的对象可以划分为
- ServletContext域
- HttpSession域
- ServletRequest域
按照被监听的内容划分为三类:
- 监听域对象自身的创建和销毁的事件监听器。
- 监听域对象中的属性的增加和删除的事件监听器。
- 监听绑定到HttpSession域中的某个对象的状态的事件监听器。
常用的监听器主要包括:
- ServletContextListener
- ServletContextAttributeListener
- HttpSessionListener
- HttpSessionAttributeListener
- ServletRequestListener
- ServletRequestAttributeListener
- HttpSessionBindingListener
- HttpSeesionActivationListener
lisenter实战
创建一个Java Web工程,在其中添加3个监听器。
创建一个ServletContext域的监听器,实现ServletContextListener接口。
public class MyServletContextListener implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println(arg0.getServletContext() + "销毁了!");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println(arg0.getServletContext() + "创建了!");
}
}
创建一个HttpSession域的监听器,实现HttpSessionListener接口。
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println(arg0.getSession() + "创建了!");
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println(arg0.getSession() + "销毁了!");
}
}
创建一个ServletRequest域的监听器,实现ServletRequestListener接口。
public class MyServletRequestListener implements ServletRequestListener{
@Override
public void requestDestroyed(ServletRequestEvent arg0) {
System.out.println(arg0.getServletRequest() + "销毁了!");
}
@Override
public void requestInitialized(ServletRequestEvent arg0) {
System.out.println(arg0.getServletRequest() + "创建了!");
}
}
在配置文件web.xml中注册3个监听器。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>webListener</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<listener>
<description>ServletContextListener</description>
<listener-class>listener.MyServletContextListener</listener-class>
</listener>
<listener>
<description>HttpSessionListener</description>
<listener-class>listener.MyHttpSessionListener</listener-class>
</listener>
<listener>
<description>ServletRequestListener</description>
<listener-class>listener.MyServletRequestListener</listener-class>
</listener>
</web-app>
当访问jsp的时候,HttpSession就会创建,编写一个jsp页面index.jsp用来观察HttpSession。
<%@ page language="java" contentType="text/html; charset=UTF-8" import="java.util.*"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>HttpSessionListener监听器监听HttpSession对象的创建</title>
</head>
<body>
创建好的Session的Id是:${pageContext.session.id}
</body>
</html>
运行项目,打开首页。
listener-index.jpg查看控制台输出,可以发现,ServletContext在初始化的时候就已经创建,用户第一次访问JSP的时候创建了HttpSession。ServletRequest在用户的每一次访问都会创建,在每次访问结束会销毁。
网友评论