文章目录
Listener
-
监听器
监听某一事件的发生,状态的改变。 -
监听器的内部机制
其实就是接口回调
接口回调
- 需求
A在执行循环,当循环到5的时候,通知B。
事先先把某一个对象传给A,当A执行到5的时候,通过这个对象来调用B中的方法,但是注意,不是直接传递B的实例,而是传递一个接口的实例过去。
package filter;
public class A {
/*
* 这是以前Java基础使用的代码
* 但是假设这个A类是早以前写好的类,这个方法内部不能直接new B(),因为B类有可能是以后写的一个类
* 所以在定义这个方法的时候,不管未来写的是B类还是C类,为了通用
* 所以定义了一种接口,只要让未来的那些类实现这个接口,然后这个方法的参数写接口类型即可
* */
// public void print(){
// for (int i = 0; i < 10; i++) {
// System.out.println("循环到了--" + i);
// if(i == 5){
// System.out.println("循环到了5,通知B");
// B b = new B();
// b.printFive();
// }
// }
// }
public void print(PrintListener listener){
for (int i = 0; i < 10; i++) {
System.out.println("循环到了--" + i);
if(i == 5){
System.out.println("循环到了5,通知B");
listener.print();
}
}
}
}
package filter;
public class B implements PrintListener{
// public void printFive(){
// System.out.println("A循环到了5,所以B的这个方法将被调用");
// }
@Override
public void print() {
System.out.println("A循环到了5,所以B的这个方法将被调用");
}
}
package filter;
public interface PrintListener {
/*
* 一旦出现了某一个事件达到了某一中状态就调用这个方法
* */
void print();
}
web中的监听器
总共有8个,划分为三中类型
- 定义一个类,实现接口
- 注册,配置监听器
- 作用:监听三个作用域的创建和销毁
request
session
application
- ServletContextListener
servletContext 创建:启动tomcat服务器的时候
servletContext 销毁:关闭服务器,从服务器移除项目的时候
public class MyServletContextListener implements ServletContextListener {
//初始化的时候调用
public void contextInitialized(ServletContextEvent sce){
System.out.println("servletContext初始化了");
}
//销毁的时候调用
public void contextDestroyed(ServletContextEvent sce){
System.out.println("servletContext销毁了");
}
}
-
ServletRequestListener
request 创建:访问服务器中的任何资源都会有请求出现。
访问html:会
访问jsp:会
访问servlet:会
request 销毁:服务器已经对这次请求做出了响应
public class MyRequestListener implements ServletRequestListener {
public void requestInitialized(ServletRequestEvent sre){
System.out.println("servletRequest创建了");
}
public void requestDestroyed(ServletRequestEvent sre){
System.out.println("servletRequest销毁了");
}
}
- HttpSessionListener
- 监听三个作用域属性状态的改变
- 监听httpSession里面存值的状态变更
监听三个作用域属性状态的改变
request ------- ServletRequestAttributeListener
session ------- HttpSessionAttributeListener
servletContext --------- ServletContextAttributeListener
- 可以监听作用域中值的添加、替换和移除动作。
public class MyHttpSession implements HttpSessionAttributeListener {
public void attributeAdded(HttpSessionBindingEvent se){
System.out.println("属性被添加了");
}
public void attributeRemoved(HttpSessionBindingEvent se){
System.out.println("属性被移除了");
}
public void attributeReplaced(HttpSessionBindingEvent se){
System.out.println("属性被替换了");
}
}
监听httpSession中值的状态的改变
这一类监听器不用注册
-
HttpSessionBindingListener
监听对象与session绑定和解除绑定的动作 -
HttpSessionActivationListener
用于监听session的值是钝化(序列化)还是活化(反序列化)的动作
钝化:把内存中的数据存储到硬盘上
活化:把硬盘中的数据读取到内存中 -
session 的钝化和活化用意何在?
session中的值可能会很多,并且我们有很长一段时间不使用这个值,那么我们可以考虑把session的值存储到硬盘中,等下一次使用的时候在从硬盘中取出来。 -
如何让session的值在一定时间内钝化?
配置即可
- 在tomcat服务器里边 conf/context.xml 里边配
对所有运行在这个服务器的项目生效 - 在 conf/Catalina/locahost/context.xml 配置
对localhost生效 - 在自己的web工程项目中的META-INF/context.xml
只对当前工程生效
Filter
过滤器:其实就是对客户端发过来的请求进行过滤。浏览器发出,然后服务器派 servlet 处理。在中间就可以过滤,其实过滤器起到的就是拦截的作用。
作用:
- 对一些敏感词汇进行过滤
- 统一设置编码
- 自动登录
如何使用 filter
- 定义一个类实现 Filter 接口
public class FilterDemo implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
chain.doFilter(req, resp);
System.out.println("来到过滤器了...");
}
public void init(FilterConfig config) throws ServletException {
}
}
- 注册过滤器
在 web.xml 中注册,手法和注册 servlet 的一样
<filter>
<filter-name>FilterDemo</filter-name>
<filter-class>filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Filter 的声明周期
- 创建
启动 Tomcat 服务器时候创建 - 销毁
在服务器停止的时候销毁
Filter 执行顺序
- 客户端发出请求,先经过过滤器,如果过滤器放行,那么才能到达 servlet。
- 如果有多个过滤器,那么他们会按照注册的映射顺序来排队。只要有一个过滤器不放行,那么后面排队的过滤器以及 servlet 都不会收到请求。
细节
- init 方法的参数 FilterConfig 可以用于获取 filter 在注册的名字以及初始化参数。其实这里的功能设计的初衷与 servletConfig 是一样的。
- 如果向放行,那么在 doFilter 方法里面操作,使用参数 chain
chain.doFilter(req, resp);
放行,让请求到达下一个目标
<url-pattern>/*</url-pattern>
写法格式与 servlet 一样
- 全路径匹配,以 / 开始:/LoginServlet
- 以目录匹配:以 / 开始,以 * 结束
- 以后缀名匹配:以 * 开始,以后缀名结束,如 .jsp,.html
- 针对 dispatcher 设置
REQUEST:只要是请求过来都拦截,默认就是 REQUEST
FORWARD:只要是转发都拦截
ERROR:页面出错发生跳转
INCLUDE:包含页面的时候就拦截
DBUtils
使用传统的方法(下边注释掉的)比较麻烦,我们使用一个工具 DBUtils 来简化代码。简化 Bean 的写法。
public class RegisterServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Map map = request.getParameterMap();
UserBean bean = new UserBean();
BeanUtils.populate(bean, map);
System.out.println(bean.toString());
} catch (Exception e) {
e.printStackTrace();
}
// String username = request.getParameter("username");
// String password = request.getParameter("password");
// String email = request.getParameter("email");
// String phone = request.getParameter("phone");
// String address = request.getParameter("address");
//
// UserBean bean = new UserBean();
// bean.setUsername(username);
// bean.setPassword(password);
// bean.setEmail(email);
// bean.setPhone(phone);
// bean.setAddress(address);
//
// System.out.println("bean===" + bean.toString());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}