笔记输出来源:拉勾教育Java就业急训营
修改时间:2021年2月2日
作者:pp_x
邮箱:[email protected]
文章目录
Filter
基本概念
- Filter本意为”过滤“的含义,是JavaWeb的三大组件之一,三大组件为:Servlet、Filter、Listener。
- 过滤器是向 Web 应用程序的请求和响应处理添加功能的 Web 服务组件。
- 过滤器相当于浏览器与Web资源之间的一道过滤网,在访问资源之前通过一系列的过滤器对请求
进行修改、判断以及拦截等,也可以对响应进行修改、判断以及拦截等。
工作方式
使用方式
- 自定义类实现Filter接口并重写doFilter方法
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 1.实现对用户访问主页面的过滤操作,也就是只有用户登录后才能访问主页面,否则一律拦截
// 判断session中是否已有用户名信息,若没有则进行拦截,否则放行
HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
HttpSession session = httpServletRequest.getSession();
Object userName = session.getAttribute("userName");
// 获取Servlet的请求路径
String servletPath = httpServletRequest.getServletPath();
// 若没有登录,则回到登录页面
if (null == userName && !servletPath.contains("login")) {
servletRequest.getRequestDispatcher("login.jsp").forward(servletRequest, servletResponse);
} else {
// 若已经登录,则放行
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy() {
}
}
- 在web.xml中配置过滤器
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.lagou.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/main.jsp</url-pattern> //登陆后要进入的页面
</filter-mapping>
Filter接口
javax.servlet.Filter
接口主要用于描述过滤器对象,可以对资源的请求和资源的响应操作进行筛选操作。- 常用的方法:
方法 | 功能 |
---|---|
void init(FilterConfig filterConfig) | 实现过滤器的初始化操作 |
void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) | 执行过滤操作的功能 |
void destroy() | 实现过滤器的销毁操作 |
filterChain.doFilter(servletRequest, servletResponse);
:放行
FilterConfig接口
javax.servlet.FilterConfig
接口主要用于描述过滤器的配置信息。- 常用方法:
方法 | 功能 |
---|---|
String getFilterName() | 获取过滤器的名字 |
String getInitParameter(String name) | 获取指定的初始化参数信息 |
Enumeration getInitParameterNames() | 获取所有的初始化操作名称 |
ServletContext getServletContext() | 获取ServletContext对象 |
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化操作正在火热进行中...");
System.out.println("获取到的过滤器名称为:" + filterConfig.getFilterName());
String userName = filterConfig.getInitParameter("userName");
System.out.println("获取到指定初始化参数的数值为:" + userName); // admin
Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
// userName password
System.out.println("获取到的初始化参数名为:" + initParameterNames.nextElement());
}
ServletContext servletContext = filterConfig.getServletContext();
System.out.println("获取到的上下文对象是:" + servletContext);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("阻拦一切不合理的访问哦!");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("销毁操作执行完毕了!");
}
}
多个过滤器的使用
- 过滤器一
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("这是第一道防线!");
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("第一道防线返回!");
}
- 过滤器二
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("这是第二道防线!");
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("第二道防线返回!");
}
<filter>
<filter-name>BFilter</filter-name>
<filter-class>com.lagou.demo02.BFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>BFilter</filter-name>
<url-pattern>*.avi</url-pattern>
</filter-mapping>
<filter>
<filter-name>AFilter</filter-name>
<filter-class>com.lagou.demo02.AFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AFilter</filter-name>
<url-pattern>*.avi</url-pattern>
</filter-mapping>
- 注意:根据配置文件中映射的先后顺序调用过滤器
- 输出结果:
这是第二道防线
这是第一道防线
第一道防线返回
第二道防线返回
过滤器优点
- 实现代码的“可插拔性”,即增加或减少某个功能模块,不会影响程序的正常执行。
- 可以将多个相同处理逻辑的模块集中写在过滤器里面,可实现重复利用、也方便代码的维护。
监听器Listener
基本概念
- Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件并进行相应的处理
- 容器产生的事件分类如下:
- 生命周期相关的事件。
- 属性状态相关的事件。
- 存值状态相关的事件。
- 底层原理是采用接口回调的方式实现。
需要进行的配置
<listener>
<listener-class>com.lagou.demo03.MyRequestListener</listener-class>
</listener>
ServletRequestListener监听器
- 在ServletRequest创建和关闭时都会通知ServletRequestListener监听器。
- 常用方法
void requestInitialized(ServletRequestEvent sre)
:实现ServletRequest对象的初始化void requestDestroyed(ServletRequestEvent sre)
:实现ServletRequest对象的销毁
public class MyRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("请求销毁了...");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("创建请求...");
}
}
ServletRequestAttributeListener监听器
- 向ServletRequest添加、删除或者替换一个属性的时候,将会通知ServletRequestAttributeListener监听器。
- 常用方法:
void attributeAdded(ServletRequestAttributeEvent srae)
:增加请求属性时触发void attributeReplaced(ServletRequestAttributeEvent srae)
:修改属性时触发void attributeRemoved(ServletRequestAttributeEvent srae)
:删除属性时触发
public class MyRequestAttributeListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("增加了属性" + servletRequestAttributeEvent.getName());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("属性" + servletRequestAttributeEvent.getName() + "被删除了" );
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("修改属性" + servletRequestAttributeEvent.getName());
}
}
HttpSessionListener监听器
- 当一个HttpSession刚被创建或者失效(invalidate)的时候,将会通知HttpSessionListener监听器。
void sessionCreated(HttpSessionEvent se)
:当一个HttpSession对象被创建时会调用这个方法void sessionDestroyed(HttpSessionEvent se)
:当一个HttpSession超时或者调用HttpSession的invalidate()方法让它销毁时,将会调用这个方法
HttpSessionAttributeListener监听器
- HttpSession中添加、删除或者替换一个属性的时候,将会通知HttpSessionAttributeListener监听器。
- 常用方法同上
public class MySessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("创建了session...");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("session销毁!");
}
}
public class MySessionAttributeListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("增加了属性" + httpSessionBindingEvent.getName());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("属性" + httpSessionBindingEvent.getName() + "被删除!");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("修改属性" + httpSessionBindingEvent.getName());
}
}
ServletContextListener监听器
- 在ServletContext创建和关闭时都会通知ServletContextListener监听器
ServletContextAttributeListener监听器
- 向ServletContext添加、删除或者替换一个属性的时候,将会通知ServletContextAttributesListener监听器
public class MyContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象创建了...");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("销毁ServletContext对象...");
}
}
public class MyContextAttributeListener implements ServletContextAttributeListener {
@Override
public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("增加了属性" + servletContextAttributeEvent.getName());
}
@Override
public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("属性" + servletContextAttributeEvent.getName() + "被删除!");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
System.out.println("修改属性" + servletContextAttributeEvent.getName());
}
}
HttpSessionBindingListener监听器
- HttpSession中绑定和解除绑定时,将会通知HttpSessionListener监听器
void valueBound(HttpSessionBindingEvent event)
:有对象绑定时调用该方法void valueUnbound(HttpSessionBindingEvent event)
:有对象解除绑定时调用该方法
public class Person implements HttpSessionBindingListener {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("对象绑定到session中了" + httpSessionBindingEvent.getName());
}
@Override
public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("解除绑定成功!");
}
}
<%
// 准备一个Person类型的对象
Person person = new Person();
person.setName("zhangfei");
person.setAge(30);
// 将对象与session对象进行绑定
session.setAttribute("person", person);
// 解除绑定
session.removeAttribute("person");
%>
HttpSessionActivationListener监听器
- 当有session数值的钝化和活化操作时,将会通知HttpSessionActivationListener监听器。
void sessionWillPassivate(HttpSessionEvent se)
:有钝化操作时调用该方法void sessionDidActivate(HttpSessionEvent se)
:有活化操作时调用该方法- 活化:硬盘到内存 反序列化 会话从新接入后从硬盘读取到内存
- 钝化:内存到硬盘 序列化 会话开启后浏览器关闭存入硬盘
public class Student implements Serializable, HttpSessionActivationListener {
private String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
@Override
public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
System.out.println("执行了钝化操作..." + httpSessionEvent.getSession());
}
@Override
public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
System.out.println("活化操作进行中...");
}
}
<head>
<title>实现session中数据的钝化和活化操作</title>
</head>
<body>
<%
// 创建Student类型的对象
Student student = new Student();
student.setName("zhangfei");
// 将数据放入到session中
session.setAttribute("student", student);
%>
</body>
- context.xml
<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true">
<!-- 配置文件存放的路径信息,可以自由指定 -->
<Store className="org.apache.catalina.session.FileStore" directory="C:\session"/>
</Manager>