目录
一、Listener监听器
1.1监听机制
1.2JavaWeb开发中常见监听器
1.3监听器练习
1.3.1监听域对象的创建与销毁
1.3.2监听域对象的属性变化
1.3.3监听session绑定javaBean对象
1.3.4定时销毁session
二、Filter过滤器
2.1Filter
2.2FilterChain
2.3Filter生命周期
2.4FilterConfig
2.5Filter配置
三、自动登录
四、MD5加密
一、Listener监听器
监听器一般用于监听Web应用中的某些对象(例如:HttpServletRequest、HttpSession、ServletContext),比如对象的创建、销毁、属性变化、修改和删除等动作的发生,然后做出相应的响应处理。当范围对象状态发生变化的时候,服务器会自动调用监听器对象中的方法。
1.1监听机制
| 名称 | 备注 |
| 事件 | 对象发生了某些改变 |
| 事件源 | 发生事件的源头 |
| 监听器 | 用于监听指定时间的对象 |
| 注册监听 | 让监听器监听某事件,必须先注册 |
1.2JavaWeb开发中常见监听器
| 监听对象 | 监听器名称 |
| ServletContext | 监听对象的创建与销毁:ServletContextListener |
| 监听对象的属性变化:ServletContextAttributeListener | |
| HttpSession | 监听对象的创建与销毁:HttpSessionListener |
| 监听对象的属性变化:HttpSessionAttributeListener | |
| HttpServletRequest | 监听对象的创建与销毁:ServletRequestListener |
| 监听对象的属性变化:ServletRequestAttributeListener | |
| javaBean | 监听javaBean对象是否绑定到了session域中:HttpSessionBindingListener |
| 监听javaBean对象的活化与钝化:HttpSessionActivationListener |
1.3监听器练习
创建一个监听器的步骤如下:
- 创建一个类,实现指定的监听器接口
- 重写接口中的方法
- 在web.xml中对监听器进行注册
1.3.1监听域对象的创建与销毁
我们测试监听一下ServletContext对象的创建与销毁,首先新建一个类,继承ServletContextListener接口,并实现其中的方法,
package Listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ServletContextListenerDemo implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {//监听ServletContext对象创建的方法
System.out.println("ServletContext对象已初始化");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {//监听ServletContext对象销毁的方法
System.out.println("ServletContext对象已销毁");
}
}
然后我们需要在web.xml中注册监听,
Listener.ServletContextListenerDemo
启动服务器和关闭服务器看看输出,
同样的,HttpSession对象会在打开index.jsp时自动创建,Session对象销毁的话有四种方式,分别为①默认超时②关闭服务器③invalidate()方法④setMaxInactiveInterval(int interval)设置超时时间,当session被销毁时也会触发监听方法。
而ServletRequest对象是处理浏览器请求的,我们打开index.jsp时,其内置就有一个servlet,打开时会调用service()方法,从而创建ServletRequest对象,当执行完service()方法后,ServletRequest对象就会被销毁。
1.3.2监听域对象的属性变化
我们以ServletRequest对象为例,首先创建监听类,实现接口中的方法,
package Listener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
public class ServletRequestAttListenerDemo implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {//监听属性添加
System.out.println("ServletRequest已添加属性");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {//监听属性删除
System.out.println("ServletRequest已删除属性");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {//监听属性替换,参数为时间源对象
System.out.println("ServletRequest已替换属性");
System.out.println(servletRequestAttributeEvent.getName()+" "+servletRequestAttributeEvent.getValue());//输出被替换的属性名和属性值
}
}
在web.xml中注册监听,
Listener.ServletRequestAttListenerDemo
然后在index.jsp首页上添加一个属性,然后替换一下属性
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
<%
request.setAttribute("name","peru");
%>
启动服务器看看输出,
1.3.3监听session绑定javaBean对象
我们首先新建一个javaBean对象,实体类User,这里我们要在javaBean对象上实现接口中的方法,
package Util;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class User implements HttpSessionBindingListener {
private String name;
private int age;
//实现get和set方法,这里省略了
@Override
public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("User对象已被绑定");
}
@Override
public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("User对象已解除绑定");
}
}
然后在index.jsp中绑定该对象,
<%@ page import="Util.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
<%
session.setAttribute("user",new User());
%>
注意此时并不需要在web.xml中注册监听,直接启动服务器就可以监听绑定事件,
因为我们的session马上就被销毁了,所以也就迅速解除绑定了。
1.3.4定时销毁session
我们可以创建一个HttpSessionListener,当session对象创建时,就将这个session对象装入到一个集合中。将集合List
我们可以通过getLastAccessedTime()方法得到上依次使用session的时间,这样就可以完成定时的操作,然后利用invalidate()方法进行销毁。
我们新建一个MyServletContextListener类,用于创建集合,并存储session对象,然后定期对不活跃的session进行移除。
package Listener.test;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSession;
import java.util.*;
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//通过事件源对象得到事件源ServletContext
ServletContext application = servletContextEvent.getServletContext();
//创建一个集合用于存储所有session对象
List list= Collections.synchronizedList(new ArrayList<>());//并且让该集合处于线程安全状态
//把集合放在application域中
application.setAttribute("sessions",list);
//创建一个计数器对象
Timer t=new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("开始扫描session");
for (Iterator iterator=list.iterator();iterator.hasNext();){
HttpSession session=(HttpSession) iterator.next();
long time = System.currentTimeMillis() - session.getLastAccessedTime();//计算session对象多久没被使用
if (time>5000){//如果超过5s没被访问
System.out.println("session移除了"+session.getId());
session.invalidate();//将session销毁
iterator.remove();//在集合中移除session对象
}
}
}
}, 2000, 5000);//延迟2s后重复执行,间隔为5s
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
然后创建MySessionListener对象,监听session的创建过程,并将创建的session放置到集合中。
package Listener.test;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.util.List;
public class MySessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
//得到application对象,得到list集合
HttpSession session = httpSessionEvent.getSession();//首先获取session对象
ServletContext application = session.getServletContext();//获取servletContext对象
List list = (List)application.getAttribute("sessions");//获取域对象中的list集合
//得到session对象,并放入到list集合中
list.add(session);
System.out.println("添加了"+session.getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
}
}
二、Filter过滤器
Filter可以对客户端访问资源进行过滤,符合条件的就可以访问,不符合条件的就拒绝访问,并且可以对目标资源访问前后进行逻辑处理操作。
2.1Filter
创建过滤器Filter主要有以下几个步骤:
- 创建一个类实现Filter接口
- 重写接口中的方法,执行过滤方法的为doFilter()
- 在web.xml文件中配置
如果在doFilter方法中没有执行FilterChain对象的doFilter方法,那么Filter过滤访问请求后不会继续执行之前的访问请求。
我们新建一个类MyFilter实现Filter接口,进行过滤拦截,
package Filter;
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("doFilter已执行");//开始拦截,执行输出语句
filterChain.doFilter(servletRequest, servletResponse);//执行完拦截语句后继续访问原来的网页,命令放行
System.out.println("结束拦截");
}
@Override
public void destroy() {
}
}
接着我们创建一个Servlet用于模拟需要访问的资源,然后在Servlet中输出一句话,
package Filter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "ServletFilterDemo")
public class ServletFilterDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ServletFilterDemo");
}
}
配置好web.xml配置文件,
MyFilter Filter.MyFilter MyFilter public static String md5(String plainText) { byte[] secretBytes = null; try { secretBytes = MessageDigest.getInstance("md5").digest( plainText.getBytes()); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("没有md5这个算法!"); } String md5code = new BigInteger(1, secretBytes).toString(16); for (int i = 0; i < 32 - md5code.length(); i++) { md5code = "0" + md5code; } return md5code; } }



