目录
HttpSessionActivationListener监听器
监听器
-
什么是监听器
监听器就是一个实现了特定接口的Java类,这个Java类用于监听另一个Java类的方法调用或者属性的改变。当被监听对象发生上述事件后,监听器某个方法将会立即被执行。
-
监听器的用途
用来监听其他对象的变化的。主要应用在图形化界面开发上。
- Java中GUI,Android
-
监听器的术语
- 事件源:指的是被监听对象(汽车)
- 监听器:指的是监听的对象(报警器)
- 事件源和监听器绑定:在汽车上安装报警器
- 事件:指的是事件源对象的改变(踹了汽车一脚)----主要功能获得事件源对象。
-
监听器的执行过程
- 入门案例
package com.toroidals.listener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
public class ListenerDemo extends JFrame {
public static void main(String[] args) {
// 1.创建小窗口对象:(被监听的对象)
ListenerDemo ld = new ListenerDemo();
// 设置窗口名称:
ld.setName("窗口");
// 设置窗口的宽高:
ld.setBounds(600, 300, 550, 450); //横向位置,纵向位置,宽度,高度
// 2.设置窗口显示:
ld.setVisible(true);
// 在事件源上绑定监听器:
ld.addWindowListener(new MyWindowListener());
}
}
/**
* 监听器对象
* @author jt
*
*/
class MyWindowListener implements WindowListener{
@Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub
System.out.println("窗口被打开!");
}
@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
ListenerDemo myFrame = (ListenerDemo) e.getSource();
System.out.println(myFrame.getName());
System.out.println("窗口关闭...");
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub
}
}
run as java application
-
Servlet中的监听器
- Servlet中的监听器简介
在Servlet中定义了多种类型的监听器,它们用于监听的事件源分别是
- ServletContext
- HttpSession
- ServletRequest
- Servlet中的监听器的分类
- 一类:监听三个域对象的创建和销毁的监听器(三个)
- 二类:监听三个域对象的属性变更(属性添加、移除、替换)的监听器(三个)
- 三类:监听HttpSession中JavaBean的状态改变(钝化、活化、绑定、解除绑定)的监听(两个)
-
ServletContextListener监听器
- 用来监听ServletContext域对象的创建和销毁的监听器。
- ServletContext创建和销毁
- ServletContext
- 创建:在服务器启动的时候,为每个web应用创建单独的ServletContext对象。
- 销毁:在服务器关闭的时候,或者项目从web服务器中移除的时候。
- ServletContextListener监听器的方法
|
| 通知将开始 Web 应用程序初始化过程。在初始化 Web 应用程序中的所有过滤器或 servlet 之前,应该通知所有 ServletContextListener 关于上下文初始化的信息。 |
|
| 通知即将关闭 servlet 上下文。在通知所有 ServletContextListener 上下文销毁之前,所有 servlet 和过滤器都已销毁。 |
- 创建监听器
package com.toroidals.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent arg0) {
//监听ServletContext对象的创建
System.out.println("ServletContext对象被创建了...");
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
//监听ServletContext对象的销毁
System.out.println("ServletContext对象被销毁了...");
}
}
- 监听器的配置(绑定监听器)
<?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_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>JspDemo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>com.toroidals.listener.MyServletContextListener</listener-class>
</listener>
...
-
ServletContextListener企业用途
- 加载框架的配置文件:
- Spring框架提供了一个核心监听器ContextLoaderListener。
- 定时任务调度:
-
HttpSessionListener监听器
- HttpSessionListener监听器作用
- 用来监听HttpSession对象的创建和销毁。
- HttpSession创建和销毁
- 创建:
- 服务器端第一次调用getSession()方法时候。
- 销毁:
- 非正常关闭服务器(正常关闭服务器session会被序列化)。
- Session过期(默认过期时间30分钟)。
- 手动调用session.invalidate()方法。
- HttpSessionListener监听器的方法
|
| 通知创建了一个会话。 |
|
| 通知某个会话即将无效。 |
- 创建监听器
package com.toroidals.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyhttpSessionListener implements HttpSessionListener{
@Override
public void sessionCreated(HttpSessionEvent arg0) {
//监听HttpSession的创建
System.out.println("HttpSession对象被创建了...");
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
//监听HttpSession的销毁
System.out.println("HttpSession对象被销毁了...");
}
}
- 监听器的配置(绑定监听器)
<listener>
<listener-class>com.toroidals.listener.MyhttpSessionListener</listener-class>
</listener>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
思考
- 访问HTML是否创建Session :不会
- 访问JSP是否创建Session :会
- 访问Servlet是否创建Session :不一定(默认没有调用getSession方法,除非代码中有getSession方法)
-
ServletRequestListener监听器
- ServletRequestListener监听器作用
- 用户监听ServletRequest对象的创建和销毁
- ServletRequest对象的创建和销毁
- 创建
- 从客户端向服务器发送一次请求,服务器就会创建request对象。
- 销毁
- 服务器对这次请求作出了响应之后,request对象就销毁了。
- ServletRequestListener监听器的方法
|
| 请求即将进入该 Web 应用程序的范围。 |
|
| 请求即将超出该 Web 应用程序的范围。 |
- 创建监听器
package com.toroidals.listener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
public class MyServletRequestListener implements ServletRequestListener{
@Override
public void requestDestroyed(ServletRequestEvent arg0) {
//监听ServletRequest的销毁
System.out.println("ServletRequest对象被销毁了");
}
@Override
public void requestInitialized(ServletRequestEvent arg0) {
//监听ServletRequest的创建
System.out.println("ServletRequest对象被创建了");
}
}
-
统计当前在线人数的案例
package com.toroidals.onlineCount;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent scte) {
// TODO Auto-generated method stub
}
@Override
public void contextInitialized(ServletContextEvent scte) {
//在服务启动时初始化一个值为0,存到ServletContext
scte.getServletContext().setAttribute("online", 0);
}
}
package com.toroidals.onlineCount;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyHttpSessionListener implements HttpSessionListener{
@Override
public void sessionCreated(HttpSessionEvent hse) {
//在session创建的时候,认为一个用户上线
//获取session
HttpSession session = hse.getSession();
System.out.println(session.getId() + "上线了...");
//获取当前在线人数(ServletContext中的值)
Integer online = (Integer) session.getServletContext().getAttribute("online");
online++;
//跟新在线人数
session.getServletContext().setAttribute("online", online);
}
@Override
public void sessionDestroyed(HttpSessionEvent hse) {
//在session销毁的时候,认为一个用户离线
//获取session
HttpSession session = hse.getSession();
System.out.println(session.getId() + "离线了...");
//获取当前在线人数(ServletContext中的值)
Integer online = (Integer) session.getServletContext().getAttribute("online");
online--;
//跟新在线人数
session.getServletContext().setAttribute("online", online);
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>当前在线人数</h1>
${ online }
</body>
</html>
配置监听器
<listener>
<listener-class>com.toroidals.onlineCount.MyHttpSessionListener</listener-class>
</listener>
<listener>
<listener-class>com.toroidals.onlineCount.MyServletContextListener</listener-class>
</listener>
-
监听三个域对象的属性变更的监听器
- ServletContextAttributeListener
- 监听ServletContext对象中的属性变更(属性添加,移除,替换)的监听器
- HttpSessionAttributeListener
- 监听HttpSession对象中的属性变更(属性添加,移除,替换)的监听器
- ServletRequestAttributeListener
- 监听ServletRequest对象中的属性变更(属性添加,移除,替换)的监听器
- 演示 HttpSessionAttributeListener 监听器
package com.toroidals.attributeAlter;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener{
@Override
public void attributeAdded(HttpSessionBindingEvent hsbe) {
System.out.println("Session中新增属性...");
}
@Override
public void attributeRemoved(HttpSessionBindingEvent hsbe) {
System.out.println("Session中属性被移除...");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent hsbe) {
System.out.println("Session中属性被更改...");
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>当前在线人数</h1>
<%
session.setAttribute("name", "李淳风");
session.setAttribute("name", "李茂贞");
session.removeAttribute("name");
%>
</body>
</html>
配置监听器
<listener>
<listener-class>com.toroidals.attributeAlter.MyHttpSessionAttributeListener</listener-class>
</listener>
-
监听HttpSession中Java类状态改变的监听器
- 第三类监听器概述
保存在Session域中的Java类可以有多种状态:绑定到session中;从session中解除绑定;随session对象持久化到一个存储设备中(钝化);随session对象从一个存储设备中恢复(活化)。
Servlet对方中定义了两个特殊的监听的接口来帮助Java类了解自己在Session域中的状态:
- HttpSessionBindingListener接口
- HttpSessionActivationListener接口,
实现这两个接口的类不需要在web.xml中进行配置。
-
HttpSessionBindingListener监听器
监听Java类在HttpSession中的绑定和解除绑定的状态的监听器:
package com.toroidals.listener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class MyHttpSessionBindingListner implements HttpSessionBindingListener{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void valueBound(HttpSessionBindingEvent arg0) {
System.out.println("MyHttpSessionBindingListener与session绑定了...");
}
@Override
public void valueUnbound(HttpSessionBindingEvent arg0) {
System.out.println("MyHttpSessionBindingListener与session解除绑定了...");
}
}
<%@page import="com.toroidals.listener.MyHttpSessionBindingListner" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
MyHttpSessionBindingListner hsbl = new MyHttpSessionBindingListner();
hsbl.setName("李茂贞");
session.setAttribute("hsbl", hsbl); //将MyHttpSessionBindingListener与session绑定
%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
session.removeAttribute("hsbl"); //将MyHttpSessionBindingListener与session解绑绑定
%>
</body>
</html>
-
HttpSessionActivationListener监听器
- 监听HttpSession中Java类的钝化和活化监听器。
<%@page import="com.toroidals.listener.MyHttpSessionActivationListener" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
MyHttpSessionActivationListener gsal = new MyHttpSessionActivationListener();
gsal.setName("李茂贞");
//在session过期或者服务器正常关闭时,session和与session绑定并继承Serializable的类都会被序列化
session.setAttribute("gsal", gsal); //将MyHttpSessionActivationListener与session绑定
%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>获取值</h3>
${ gsal.name }
</body>
</html>
package com.toroidals.listener;
import java.io.Serializable;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
/*
* 继承Serializable才能随session一起被序列化,否则会在session被序列化之前删除
*/
public class MyHttpSessionActivationListener implements HttpSessionActivationListener,Serializable{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void sessionDidActivate(HttpSessionEvent arg0) {
System.out.println("MyHttpSessionActivationListener被活化了...");
}
@Override
public void sessionWillPassivate(HttpSessionEvent arg0) {
System.out.println("MyHttpSessionActivationListener被钝化了...");
}
}
正常关闭tomcat服务测试,如果 MyHttpSessionActivationListener 类没有实现 Serializable,在session被序列化时session中存储的MyHttpSessionActivationListener 对象属性会被删除,其它属性正常被序列化
<%@page import="com.toroidals.listener.MyHttpSessionActivationListener" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
MyHttpSessionActivationListener gsal = new MyHttpSessionActivationListener();
gsal.setName("李茂贞");
//在session过期或者服务器正常关闭时,session和与session绑定并继承Serializable的类都会被序列化
session.setAttribute("gsal", gsal); //将MyHttpSessionActivationListener与session绑定
session.setAttribute("name", "李淳风");
MyHttpSessionActivationListener mgsal = new MyHttpSessionActivationListener("袁天罡");
session.setAttribute("namem", mgsal.getName());
%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>获取值session.setAttribute("gsal", gsal);</h3>
${ gsal.name }
<%= session.getAttribute("gsal") %>
<h3>获取值session.setAttribute("name", "李淳风");</h3>
${ name }
<h3>获取值session.setAttribute("namem", mgsal.getName());</h3>
${ namem }
</body>
</html>
- 使 MyHttpSessionActivationListener 实现 Serializable 接口使其能被序列化
public class MyHttpSessionActivationListener implements HttpSessionActivationListener,Serializable{
- 配置完成session的序列化和反序列化(避免测试时启停tomcat,通过配置设置session的失效时间)
Context标签可以配置在:
tomcat/conf/context.xml :所有tomcat下虚拟主机和虚拟目录下的工程都会序列化session
tomcat/conf/Catalina/localhost/context.xml :localhost虚拟主机下的所有项目会序列化session
工程/META-INF/context.xml :当前工程才会序列化session。
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="itheima"/>
</Manager>
</Context>
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="itheima"/>
</Manager>
</Context>
<%@page import="com.toroidals.listener.MyHttpSessionActivationListener" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
MyHttpSessionActivationListener gsal = new MyHttpSessionActivationListener();
gsal.setName("李茂贞");
//在session过期或者服务器正常关闭时,session和与session绑定并继承Serializable的类都会被序列化
session.setAttribute("gsal", gsal); //将MyHttpSessionActivationListener与session绑定
session.setAttribute("name", "李淳风");
MyHttpSessionActivationListener mgsal = new MyHttpSessionActivationListener("袁天罡");
session.setAttribute("mgsal", mgsal.getName());
%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>获取值session.setAttribute("gsal", gsal);</h3>
${ gsal.name }
<h3>获取值session.setAttribute("name", "李淳风");</h3>
${ session.name }
<h3>获取值session.setAttribute("mgsal", mgsal.getName());</h3>
${ session.mgsal }
${ mgsal.name }
</body>
</html>
-
Filter 过滤器
Filter称为过滤器,它是Servlet技术中最实用的技术,web开发人员通过Filter技术,对web服务器所管理的资源(JSP,Servlet,静态图片或静态html文件)进行拦截,从而实现一些特殊的功能。
Filter就是过滤从客户端向服务器发送的请求。
package com.toroidals.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 FilterDemo01 implements Filter{
@Override
public void destroy() {
System.out.println("过滤器FilterDemo01被销毁了...");
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
System.out.println("FilterDemo01执行了...");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("过滤器FilterDemo01被初始化了...");
}
}
- 配置过滤器
<!-- 过滤器 -->
<filter>
<filter-name>FilterDemo01</filter-name>
<filter-class>com.toroidals.filter.FilterDemo01</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo01</filter-name>
<!-- /*拦截所有请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
package com.toroidals.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 FilterDemo01 implements Filter{
@Override
public void destroy() {
System.out.println("过滤器FilterDemo01被销毁了...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("FilterDemo01执行了...");
// 放行
chain.doFilter(request, response);
//System.out.println("FilterDemo01执行结束了...");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("过滤器FilterDemo01被初始化了...");
}
}
-
FilterChain对象的概述
FilterChain过滤器链:在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为是一个过滤器链。
Web服务器根据Filter在web.xml文件中的注册顺序(mapping的配置顺序)决定先调用那个Filter。依次调用后面的过滤器,如果没有下一个过滤器,调用目标资源
- FilterChain的演示
FilterDemo01、FilterDemo02、FilterDemo03类似
package com.toroidals.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 FilterDemo01 implements Filter{
@Override
public void destroy() {
System.out.println("过滤器FilterDemo01被销毁了...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("FilterDemo01执行了...");
// 放行
chain.doFilter(request, response);
System.out.println("FilterDemo01执行结束了...");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("过滤器FilterDemo01被初始化了...");
}
}
-
Filter的生命周期
Filter的创建和销毁是由web服务器负责。
- Web应用程序启动的时候,web服务器创建Filter的实例对象。并调用其init方法进行初始化(filter对象只会创建一次,init方法也只会执行一次)。
- 每次filter进行拦截的时候,都会执行doFilter的方法。
- 当服务器关闭的时候,应用从服务器中移除的时候,服务器会销毁Filter对象。
启动tomcat服务,Filter被初始化
发送请求(拦截范围之内的请求),执行doFilter方法
正常关闭服务器,执行destroy方法
-
FilterConfig对象的概述
- FilterConfig对象的作用
用来获得Filter的相关的配置的对象。
- FilterConfig对象的API
package com.toroidals.filter;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/*
* FilterConfig演示
*/
public class FilterDemo04 implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("过滤器FilterDemo03被初始化了...");
//获取Filter名称
String filterName = filterConfig.getFilterName();
System.out.println("过滤器名称: " + filterName);
//获取指定过滤器初始化参数的值
String userName = filterConfig.getInitParameter("userName");
String password = filterConfig.getInitParameter("passWord");
System.out.println("userName:" + userName + ", password: " + password);
//获取所有过滤器初始化参数的名称和值
Enumeration<String> names = filterConfig.getInitParameterNames();
while(names.hasMoreElements()) {
String name = names.nextElement();
String value = filterConfig.getInitParameter(name);
System.out.println("name:" + name + ", value: " + value);
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 放行
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("过滤器FilterDemo03被销毁了...");
}
}
- 配置过滤器
<!-- 过滤器 -->
<filter>
<filter-name>FilterDemo04</filter-name>
<filter-class>com.toroidals.filter.FilterDemo04</filter-class>
<init-param>
<param-name>userName</param-name>
<param-value>李茂贞</param-value>
</init-param>
<init-param>
<param-name>passWord</param-name>
<param-value>wswsadadbaba</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FilterDemo04</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-
过滤器的相关配置
- <url-pattern>的配置
- 完全路径匹配 :以/开始 比如/aaa /aaa/bbb
- 目录匹配 :以/开始 以*结束 比如/* /aaa/* /aaa/bbb/*
- 扩展名匹配 :不能以/开始 以*开始 比如*.jsp *.do *.action
- <servlet-name>的配置
专门以Servlet的配置的名称拦截Servlet。
<!-- 过滤器 -->
<servlet>
<description></description>
<display-name>SkipDemo</display-name>
<servlet-name>SkipDemo</servlet-name>
<servlet-class>com.toroidals.request.SkipDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SkipDemo</servlet-name>
<url-pattern>/SkipDemo</url-pattern>
</servlet-mapping>
<filter>
<filter-name>FilterDemo05</filter-name>
<filter-class>com.toroidals.filter.FilterDemo05</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo05</filter-name>
<servlet-name>SkipDemo</servlet-name>
</filter-mapping>
- <dispatcher>的配置
- 默认的情况下过滤器会拦截请求。如果进行转发(需要拦截这次转发)。
- dispatcher的取值
- REQUEST :默认值。默认过滤器拦截的就是请求。
- FORWARD:转发。
- INCLUDE :页面包含的时候进行拦截
- ERROR :页面出现全局错误页面跳转的时候进行拦截
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>demo01执行了</h3>
<% System.out.println("demo01执行了..."); %>
<jsp:forward page="/demo02.jsp"></jsp:forward>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>demo02执行了</h3>
<% System.out.println("demo02执行了..."); %>
</body>
</html>
配置仅拦截转发
<!-- 过滤器 -->
<filter>
<filter-name>FilterDemo05</filter-name>
<filter-class>com.toroidals.filter.FilterDemo05</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo05</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
配置同时拦截请求和转发
<!-- 过滤器 -->
<filter>
<filter-name>FilterDemo05</filter-name>
<filter-class>com.toroidals.filter.FilterDemo05</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo05</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
-
权限验证过滤器
现在一个网站上需要有登录的功能,在登录成功后,重定向到后台的成功页面(后台的页面有很多)。如果现在没有登录直接在地址栏上输入后台页面地址。
编写一个过滤器:可以对没有登录的用户进行拦截。(没有登录,回到登录页面。如果已经登录,放行。)
- 拦截器类
package com.toroidals.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.HttpSession;
import com.toroidals.domain.User;
/**
* 权限验证的过滤器
*/
public class PrivilegeFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("开始执行PrivilegeFilter的doFilter方法...");
//将ServletRequest对象强转为HttpServletRequest对象
HttpServletRequest hrequest = (HttpServletRequest)request;
//获取session
HttpSession session = hrequest.getSession();
User existUser = (User) session.getAttribute("existUser");
if (existUser == null) {
//没有登录
hrequest.setAttribute("msg", "没有登录,请先登录!");
hrequest.getRequestDispatcher("/login.jsp").forward(hrequest, response);
}else {
//已经登录,放行
chain.doFilter(hrequest, response);
}
System.out.println("PrivilegeFilter的doFilter方法执行完毕...");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
配置拦截器,拦截/menu目录下所有的请求
<filter>
<filter-name>PrivilegeFilter</filter-name>
<filter-class>com.toroidals.filter.PrivilegeFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrivilegeFilter</filter-name>
<url-pattern>/menu/*</url-pattern>
</filter-mapping>
-
过滤器解决get/post提交中文数据乱码
- 案例需求
网站,需要向后台提交中文的数据(有可能是GET也有可能是POST)。中文处理根据不同的请求方式,处理的方式也是不一样的。
需要调用request.getParameter();方法接收数据,但是这个时候无论是get还是post接收的数据都是存在乱码。现在调用request.getParameter()方法无论是get还是post请求提交的中文,都没有乱码。
- 增强一个类的方法
通过上面的分析,现在增强request的getParameter的方法。增强的过程要写在过滤器中。
- 如何增强一个类中的方法?
- 继承
- 必须要能够控制这个类的构造。
- 装饰者
- 被增强的类和增强的类需要实现相同的接口。
- 在增强的类中获得被增强的类的引用。
- 缺点:接口中的方法过多,重写很多其他的方法。
- 动态代理
- 类需要实现接口。
- 继承
通用转码拦截器
package com.toroidals.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;
public class GenericEncodingFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("开始执行GenericEncodingFilter的doFilter方法");
// 在过滤器中增强request对象,并将增强后的request对象传递给Servlet:
HttpServletRequest hrequest = (HttpServletRequest) request;
// 增强hrequest:
MyHttpServletRequest mhreqesut = new MyHttpServletRequest(hrequest);
chain.doFilter(mhreqesut, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
装饰者模式,增强HttpServletRequest的对象
package com.toroidals.filter;
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class MyHttpServletRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyHttpServletRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String parameter) {
//获取的请求方式
String method = request.getMethod();
if ("get".equalsIgnoreCase(method)) {
// get方式的请求
String value = super.getParameter(parameter);
// System.out.println(value);
// try {
// value = new String(value.getBytes("ISO-8859-1"),"UTF-8");
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
// System.out.println(value);
return value;
}else if ("post".equalsIgnoreCase(method)) {
// post方式的请求
try {
request.setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return super.getParameter(parameter);
}
}
配置拦截器
<filter-name>GenericEncodingFilter</filter-name>
<filter-class>com.toroidals.filter.GenericEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>GenericEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>get提交方式</h3>
<form action="${ pageContext.request.contextPath }/SubmitData" method="get">
姓名:<input type="text" name="name" /><br>
<input type="submit" value="提交">
</form>
<br>
<h3>post提交方式</h3>
<form action="${ pageContext.request.contextPath }/SubmitData" method="post">
姓名:<input type="text" name="name" /><br>
<input type="submit" value="提交">
</form>
</body>
</html>
没有拦截的效果,post请求方式出现乱码
拦截转码之后