Java-监听器过滤器

一、监听器

(一)知识点1:监听器的作用

1.定义

  • 当事件发生的时候,需要进行一些处理,就可以使用监听器处理.

2.作用

  • 监听器监听的是事件,当事件发生的时候,监听器进行相应的处理.

(二)知识点2:监听器相关API

1.事件类

  • 事件类定义了事件类型。Servlet API定义了6种事件类型:

上下文相关事件

  ①ServletContextEvent:上下文事件
  • 1)触发时机
    • 当上下文对象发生改变,比如:创建上下文,销毁上下文的时候,会触发上下文事件

  • 2)创建上下文
    • 服务器启动的时候会触发创建上下文事件
  • 3)销毁上下文
    • 服务器停止的时候会触发销毁上下文事件
  ②ServletContextAttributeEvent:上下文属性事件
  • 1)触发时机
    • 当上下文的属性发生改变,如添加,删除,覆盖上下文的属性时,会触发上下文属性事件
  • 2)添加上下文的属性
    • 调用servletContext.setAttribute(name,value)方法的时候会触发上下文属性事件
  • 3)删除上下文属性
    • 调用servletContext.removeAttribute(name)方法的时候会触发上下文属性事件
  • 4)覆盖上下文属性
    • 调用servletContext.setAttribute(name,value)方法的时候会触发上下文属性事件

请求相关事件

  ①ServletRequestEvent:请求事件
  • 1)触发时机
    • 请求对象发生改变的时候,创建请求对象,销毁请求对象的时候会触发请求事件.
  • 2)创建请求对象
    • 当客户端浏览器请求一个servlet的时候就会创建请求对象,就会触发请求事件
  • 3)销毁请求对象
    • 当服务器将响应发送给客户端浏览器以后请求对象被销毁,也会触发请求事件
  ②ServletReqeustAttributeEvent:请求属性事件
  • 1)触发时机
    • 当请求属性发生改变,如:添加,删除,覆盖请求的属性,会触发请求属性事件
  • 2)添加请求属性
    • 调用request.setAttribute(name,value)方法时会触发请求属性事件
  • 3)删除请求属性
    • 调用request.removeAttribute(name)方法时会触发请求属性事件
  • 4)覆盖请求属性
    • 调用request.setAttribute(name,value)方法时会触发请求属性事件

会话相关事件

  ①HttpSessionEvent会话事件
    • 会话对象发生改变,创建会话对象,销毁会话对象,活化或者钝化会话对象,会触发会话事件.
  • 1)创建会话对象
    • 调用request.getSession()方法或者request.getSession(true)创建session会话对象,会触发会话事件
  • 2)销毁会话对象
    • 默认30分钟.销毁会话对象,会触发会话事件
    • web.xml配置<session-config> 50分钟 销毁会话对象,会触发会话事件
    • 调用session.invalidate()方法销毁会话对象,会触发会话事件
    • 调用session.setMaxInactiveInterval(多少秒)方法销毁会话对象,会触发会话事件
  • 3)活化会话对象
    • session会话对象从磁盘取出反序列化到内存形成session会话对象,活化会话对象,会触发会话事件
  • 4)钝化会话对象
    • session会话对象序列化到磁盘,钝化会话对象,会触发会话事件
  ②HttpSessionBindingEvent会话绑定事件
  • 1)触发时机
    • 当会话属性发生改变,如:添加,删除,覆盖会话的属性,会触发会话绑定事件
  • 2)添加会话属性  
    • 调用session.setAttribute(name,value)方法时会触发请求绑定事件
  • 3)删除会话属性
    • 调用session.removeAttribute(name)方法时会触发请求绑定事件
  • 4)覆盖会话属性
    • 调用session.setAttribute(name,value)方法时会触发请求绑定事件

总结

  • 什么是监听器?  
    • 当事件发生的时候,需要使用监听器进行处理
  • 监听器的作用  
    • 监听事件对象,事件发生时进行处理
  • 监听器事件类(6种,3大类)
    • 上下文相关事件
      • 上下文事件ServletContextEvent 上下文对象发生改变
        • 创建(服务器启动)
        • 销毁(服务器停止)
      • 上下文属性事件ServletContextAttributeEvent 上下文属性发生改变
        • 添加(setAttribute(name,value)) 删除(removeAttribute(name)) 覆盖属性(setAttribute(name,value))
    • 请求相关事件
      • 请求事件ServletReqeustEvent 请求对象发生改变
        • 创建(请求servlet)
        • 销毁(返回响应过程结束)
      • 请求属性事件ServletReqeustAttributeEvent 请求属性发生改变 添加、删除、覆盖属性
    • 会话相关事件
      • 会话事件HttpSessionEvent 会话对象发生改变
        • 创建(request.getSession(true))
        • 销毁(30分钟 50分钟 invalidate() setMaxInactiveInterval(秒))
        • 活化 反序列化 从磁盘取出反序列化到内存得到会话对象
        • 钝化 序列化 把会话对象序列化到磁盘
      • 会话绑定事件HttpSessionBindingEvent 会话属性发生改变 添加、删除、覆盖属性

2.监听器接口

监听器接口定义了监听事件的方法

Servlet API中定义了8种监听器接口,用来监听不同的事件类型

上下文相关的监听器

  • ①上下文监听器ServletContextListener,监听上下文事件ServletContextEvent
  • ②上下文属性监听器ServletContextAttributeListener,监听ServletContextAttributeEvent上下文属性事件

请求相关的监听器

  • ①请求监听器ServletRequestListener,监听请求事件ServletRequestEvent
  • ②请求属性监听器ServletRequestAttributeListener,监听请求属性事件ServletRequestAttributeEvent

会话相关的监听器

  • ①会话监听器HttpSessionListener,监听会话事件HttpSessionEvent
  • ②会话活化监听器HttpSessionActivationListener,监听会话事件HttpSessionEvent
  • ③会话属性监听器HttpSessionAttributeListener,监听会话绑定事件HttpSessionBindingEvent
  • ④会话绑定监听器 HttpSessionBindingListener,监听会话绑定事件HttpSessionBindingEvent

(三)知识点3:监听器的开发与配置

  ServletContextListener

  1. 写一个类实现XXXListener接口
  2. 重写接口中的方法,实现监听的功能
  3. web.xml配置listener
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <listener>
        <listener-class>com.tjetc.listener.MyServletContextListener</listener-class>
    </listener>
</web-app>

课堂练习

目标

  • 写上下文监听器,服务器启动和停止,是否能监听

步骤

  • ①创建MyContextListner,实现上下文监听器接口
  • ②重写接口中的方法,实现监听的功能
package com.tjetc.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("MyServletContextListener.contextInitialized()" + sce.toString());
        // System.out.println("MyServletContextListener.contextInitialized()" + sce.getServletContext());
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("MyServletContextListener.contextDestroyed()" + sce.toString());
    }
}

测试服务器启动和停止监听器是否监听

(四)知识点4:上下文相关监听器

  ServletContextAttributeListener

  1. 写一个类实现XXXListener接口
  2. 重写接口中的方法,实现监听的功能
  3. web.xml配置listener
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.tjetc.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <listener>
        <listener-class>com.tjetc.listener.MyContextAttributeListener</listener-class>
    </listener>
</web-app>

课堂练习

目标

  • 创建上下文属性监听器,测试触发时机

步骤

  • ①创建MyContextAttributeListener,实现ServletContextAttributeListener接口
  • ②重写接口的方法
  • ③写MyContextAttributeServlet,向上下文添加属性,覆盖属性,删除属性
  • ④运行MyContextAttributeServlet
package com.tjetc.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        servletContext.setAttribute("username", "kelly");
        /*ServletContext servletContext1 = req.getServletContext();
        servletContext1.setAttribute("username","jack");*/
        servletContext.setAttribute("username", "update");
        servletContext.removeAttribute("username");
    }
}
package com.tjetc.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
public class MyContextAttributeListener implements ServletContextAttributeListener {
    // 添加属性
    @Override
    public void attributeAdded(ServletContextAttributeEvent event) {
        System.out.println("MyContextAttributeListener.attributeAdded():");
        System.out.println("添加的属性名:" + event.getName() + ",属性值:" + event.getValue());
    }
    //删除属性
    @Override
    public void attributeRemoved(ServletContextAttributeEvent event) {
        System.out.println("MyContextAttributeListener.attributeRemoved():");
        System.out.println("删除的属性名:" + event.getName() + ",属性值:" + event.getValue());
    }
    //覆盖属性
    @Override
    public void attributeReplaced(ServletContextAttributeEvent event) {
        System.out.println("MyContextAttributeListener.attributeReplaced():");
        System.out.println("覆盖的属性名:" + event.getName() + ",覆盖前的属性值:" + event.getValue());
    }
}

(五) 知识点5:会话相关监听器

HttpSessionListener:会话监听器,当会话对象被创建后或销毁前需要一些自定义处理时,可以用此监听器监听;

HttpSessionActivationListener:会话活化监听器,会话对象存在于服务器端,只要没有失效,服务器就得分配空间给其使用;为了能够提高使用效率,服务器有内在的活化钝化机制,可以将暂时不使用的会话对象钝化到外存,需要使用时再活化到内存。当活化后或钝化前需要一些自定义处理时,可以使用该监听器;

HttpSessionAttributeListener:会话属性监听器,当会话中的属性被添加、删除、替换时,要进行一些自定义处理时,可以使用该监听器,使用时可以用事件对象获取属性的名字等信息。

HttpSessionBindingListener:会话绑定监听器,当类实现了HttpSessionBindingListener接口后,该类对象绑定或解除绑定到会话时,就会被该监听器监听。绑定指的是调用setAttribute方法,解除绑定指的是调用removeAttribute方法,或者会话超时、会话失效等。

(六)HttpSessionAttributeListener和HttpSessionBindingListener的区别

  • 只有实现了HttpSessionBindingListener的类 在和session绑定、解除绑定时触发其事件,valueBound(),valueUnBound()。
  • 监听器实现了HttpSessionAttributeListener后 任何对象(不论其是否实现了AttributeListener)在变化时均触发对应的事件,attributeAdded(HttpSessionBindingEvent),attributeRemoved(HttpSessionBindingEvent),attributeReplaced(HttpSeesionEvent)

1.课堂练习

目标

测试HttpSessionBindingListener:会话绑定监听器,当类实现了HttpSessionBindingListener接口后,该类对象绑定或解除绑定到会话时,就会被该监听器监听.(当类实现了HttpSessionBindingListener接口的类需要在web.xml配置)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>TestSessionBindingServlet</servlet-name>
        <servlet-class>com.tjetc.servlet.TestSessionBindingServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestSessionBindingServlet</servlet-name>
        <url-pattern>/session</url-pattern>
    </servlet-mapping>
</web-app>

步骤

①创建User类实现HttpSessionBindingListener接口,重写接口valueBound()和valueUnbound()方法,写监听的逻辑
②创建MySessionBindingServlet,创建user对象,将user对象绑定到session,解绑
③运行MySessionBindingServlet
package com.tjetc.entity;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class User implements HttpSessionBindingListener {
    private String username;
    private int age;
    public User(String username, int age) {this.username = username;this.age = age;}
    //User对象添加到Session时触发
    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("User.valueBound()");
        System.out.println(event.getName());
        System.out.println(event.getValue());
    }
    //User对象从Session中移除时触发
    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {System.out.println("User.valueUnbound()");}
    public String getUsername() {return username;}
    public void setUsername(String username) {this.username = username;}
    public int getAge() { return age;}
    public void setAge(int age) {this.age = age;}
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.tjetc.servlet;
import com.tjetc.entity.User;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class TestSessionBindingServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        User user = new User("session", 21);
        HttpSession session = req.getSession();//将user对象绑定到session
        session.setAttribute("user", user);
        session.removeAttribute("user"); //解绑
    }
}

2.课堂练习

 设计一个学生对象Student,当将该学生对象存入 session中时,他的年龄增加10岁,当将这个学生对象从session中删除时,他的年龄减少5岁。

思路:

1.创建Student类,实现HttpSessionBindingListener2.重写接口的2个方法valueBound()加10岁 valueUnbound 减5岁3.创建servlet测试. 

3.会话属性监听器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>TestSessionAttributeServlet</servlet-name>
        <servlet-class>com.tjetc.servlet.TestSessionAttributeServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestSessionAttributeServlet</servlet-name>
        <url-pattern>/sessionAttribute</url-pattern>
    </servlet-mapping>
    <listener>
        <listener-class>com.tjetc.listener.MyHttpSessionAttributeListener</listener-class>
    </listener>
</web-app>

思路:

  1. 写一个类实现HttpSessionAttributeListener接口
  2. 重写接口的方法
  3. 写servlet,向session添加属性,覆盖属性,移除属性
  4. 启动服务器,访问servlet
package com.tjetc.listener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        System.out.println("MyHttpSessionAttributeListener.attributeAdded()");
        System.out.println("添加的属性名:" + event.getName());
        System.out.println("添加的属性值:" + event.getValue());
    }
    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
        System.out.println("MyHttpSessionAttributeListener.attributeRemoved()");
        System.out.println("删除的属性名:" + event.getName());
        System.out.println("删除的属性值:" + event.getValue());
    }
    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {
        System.out.println("MyHttpSessionAttributeListener.attributeReplaced()");
        System.out.println("覆盖的属性名:" + event.getName());
        System.out.println("覆盖前的属性值:" + event.getValue());
        System.out.println("覆盖后的属性值:" + event.getSession().getAttribute(event.getName()));
    }
}
package com.tjetc.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class TestSessionAttributeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.setAttribute("name", "sessionAttribute");
        session.setAttribute("name", "update");
        session.removeAttribute("name");
    }
}

4.会话活化监听器

  • 在web下创建META-INF文件夹,创建xml

  

<?xml version="1.0" encoding="UTF-8" ?>
<Context>
    <!-- maxIdleSwap:session中的对象多长时间不使用就钝化 单位:分钟-->
    <!-- directory:钝化后的对象的文件写到磁盘的哪个目录下 配置钝化的对象文件在 work/catalina/localhost/钝化文件 -->
    <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1" saveOnRestart="true">
        <Store className="org.apache.catalina.session.FileStore" directory="c:/20220614"/>
    </Manager>
</Context>
  • 写实体类Customer,实现HttpSessionActivationListener,Serializble
package com.tjetc.entity;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;
public class Customer implements HttpSessionActivationListener, Serializable {
    private String name;
    private int age;
    public Customer() { }
    public Customer(String name, int age) { this.name = name;this.age = age; }
    //钝化(序列化)回调
    @Override
    public void sessionWillPassivate(HttpSessionEvent se) {
        System.out.println("Customer.sessionWillPassivate()");
        Object customer = se.getSession().getAttribute("customer");
        System.out.println(customer);
    }
    //活化(反序列化)回调
    @Override
    public void sessionDidActivate(HttpSessionEvent se) {
        System.out.println("Customer.sessionDidActivate()");
        Object customer = se.getSession().getAttribute("customer");
        System.out.println(customer);
    }
    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 "Customer{" +"name='" + name + '\'' + ", age=" + age + '}';
    }
}
  • 创建ActiveServlet,创建Customer对象,存储到session中
package com.tjetc.servlet;
import com.tjetc.entity.Customer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class ActiveServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Customer kelly = new Customer("kelly", 21);
        HttpSession session = req.getSession();
        session.setAttribute("customer", kelly);
    }
}

  • 写Active2Servlet,取customer对象,在控制台打印
package com.tjetc.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class Active2Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        Object customer = session.getAttribute("customer");
        System.out.println(customer);
    }
}

  • 停止Tomcat,再启动,用Active2Servlet,取customer对象,在控制台打印

(七)总结

  • 什么是监听器?
    • 当事件发生的时候,需要使用监听器进行处理
  • 监听器的作用
    • 监听事件对象,事件发生时进行处理
  • 监听器事件类(6种3大类)
    • 上下文相关事件
      • 上下文事件ServletContextEvent 上下文对象发生改变 创建(服务器启动) 销毁(服务器停止)
      • 上下文属性事件ServletContextAttributeEvent 上下文属性发生改变 添加(setAttribute(name,value)) 删除(removeAttribute(name)) 覆盖属性(setAttribute(name,value))
    • 请求相关事件
      • 请求事件ServletRequestEvent 请求对象发生改变 创建(请求servlet) 销毁(返回响应过程结束)
      • 请求属性事件ServletRequestAttributeEvent 请求属性发生改变 添加(setAttribute(name,value)) 删除(removeAttribute(name)) 覆盖属性(setAttribute(name,value))
    • 会话相关事件
      • 会话事件HttpSessionEvent 会话对象发生改变
        • 创建(request.getSession(true))
        • 销毁(30分钟 50分钟 invalidate() setMaxInactiveInterval(秒))
        • 活化 反序列化 从磁盘取出反序列化到内存得到会话对象
        • 钝化 序列化 把会话对象序列化到磁盘
      • 会话绑定事件HttpSessionBindingEvent 会话属性发生改变 添加(setAttribute(name,value)) 删除(removeAttribute(name)) 覆盖属性(setAttribute(name,value))
  • 监听器接口(8种,3大类)

              1.上下文相关监听器

                     1.上下文监听器ServletContextListener  监听ServletContextEvent事件

                     2.上下文属性监听器ServletContextAttributeListener 监听ServletContextAttributeEvent事件

              2.请求相关监听器

                     1.请求监听器ServletRequestListener 监听ServletRequestEvent事件

                     2.请求属性监听器ServletRequestAttributeListener 监听ServletRequestAttributeEvent事件

              3.会话相关监听器

                     1.会话监听器HttpSessionLisner 监听HttpSessionEvent事件

                     2.会话活化监听器HttpSessionActivationListener 监听HttpSessionEvent事件

                     3.会话属性监听器HttpSessionAttributeListener 监听HttpSessionBindingEvent事件

                     4.会话绑定监听器HttpSessionBindingListener 监听HttpSessionBindingEvent事件

5.监听器开发

       1.Web项目

       2.new-listener-包名和类名-选择监听器接口,web.xml-listener-Listner-class-类的全路径名

       3.重写接口的方法,实现监听的功能

       4.测试,如:启动服务器和停止服务器(需要到tomcat安装目录shutdown.bat)

总结提问:

Servlet规范中定义了多少种监听器事件,多少种监听器接口?

       6种监听器事件

       8种监听器接口

编写监听器的步骤是什么?

       1.Web项目

       2.new-listener-包名和类名-选择监听器接口,web.xml-listener-Listner-class-类的全路径名

       3.重写接口的方法,实现监听的功能

       4.测试,如:启动服务器和停止服务器(需要到tomcat安装目录shutdown.bat)

如何配置监听器?web.xml

<listener>
    <listener-class>xxx.yyy.类名</listener-class>
</listener>

二、过滤器

(一)过滤器的作用

  • 把通用的、相同的处理代码用过滤器实现,可以共享,然后在web.xml中将过滤器配置给相关的资源使用即可

  

(二)过滤器的开发方法

  • 写一个类实现Filter接口
  • 重写Filter接口的三个方法

  

  • IDE开发工具开发过滤器的步骤:(也可以自己建包和类)

  

  • 在doFilter()方法写逻辑:out.println("MyFilter.doFilter()...");  
  • 创建servlet,运行servlet测试.
    1. 放行 执行doFilter(request,response)
    2. 不放行 不执行doFilter(request,response)
  • FilterChain 过滤器链

    • 例如:验证是否的登录过,没有登录,返回到登录页面或者返ijson,需要的登录

          1、不处理,则认为链条断掉,后续的filter和servlet都不会访问
          2、 filterChain.doFilter(servletRequest,servletResponse);
                放行,执行后续的filter和servlet

package com.tjetc.filter;
import javax.servlet.*;
import java.io.IOException;
public class HelloFilter implements Filter {
    //初始化 调用一次 Tomcat启动时调用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("HelloFilter.init()");
    }
    //销毁 调用一次 Tomcat销毁时调用,释放资源
    @Override
    public void destroy() {
        System.out.println("HelloFilter.destroy()");
    }
    /** 每次filter拦截到请求时调用 调用多次
     * @param servletRequest      请求对象
     * @param servletResponse     响应对象
     * @param filterChain     过滤器链对象
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("HelloFilter.doFilter()");
        /*FilterChain 过滤器链
            1、不处理,则认为链条断掉,后续的filter和servlet都不会访问
            2、 filterChain.doFilter(servletRequest,servletResponse);
                放行,执行后续的filter和servlet
        */
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

(三)过滤器的各个方法执行顺序

  • 构造方法
  • init(filterConfig)初始化方法
  • doFilter()方法
  • destroy()方法
package com.tjetc.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("<h1>Hello Servlet</h1>");
    }
}

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>HelloFilter</filter-name>
        <filter-class>com.tjetc.filter.HelloFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HelloFilter</filter-name>
        <url-pattern>/*</url-pattern><!-- /* 所有访问,都经过-->
    </filter-mapping>
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.tjetc.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

  

(四)FilterConfig接口的方法

package com.tjetc.filter;
import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration;
public class HelloFilter implements Filter {
    //初始化 调用一次 Tomcat启动时调用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("HelloFilter.init()");
        String filterName = filterConfig.getFilterName();
        System.out.println("filterName=" + filterName);
        //获取所有初始化参数的名字
        Enumeration<String> names = filterConfig.getInitParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            //获取初始化参数的值
            String nameValue = filterConfig.getInitParameter(name);
            System.out.println(name + ":" + nameValue);
        }
        //获取上下文对象
        ServletContext servletContext = filterConfig.getServletContext();
        System.out.println("上下文对象:" + servletContext);
    }
    @Override
    public void destroy() {
        System.out.println("HelloFilter.destroy()");
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("HelloFilter.doFilter()");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

(五)FilterChain接口的方法

(六)编码过滤器

package com.tjetc.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CodeFilter implements Filter {
    //定义编码
    private String charset = "utf-8";
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        if (charset != null || "".equals(charset)) {
            charset = filterConfig.getInitParameter("charset");
        }
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //转换
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        //设置参数编码
        req.setCharacterEncoding(charset);
        resp.setCharacterEncoding(charset);
        resp.setContentType("text/html;charset=" + charset);
        //过滤器链放行
        filterChain.doFilter(req, resp);
    }
    @Override
    public void destroy() {}
}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
        <base href="<%=request.getContextPath()%>/">
    </head>
    <body>
        <img src="static/1.jpg">
    </body>
</html>

package com.tjetc.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("<h1>Hello Servlet 欢迎您</h1>");
    }
}

(七)总结

1.过滤器的作用

       把相同通用的代码用过滤器实现,会让目标资源共享

  • 过滤器的开发方法
    • 写一个类实现Filter接口
    • 重写接口的3个方法
    • doFilter()写处理逻辑.
      • doFilter()放行
      • 不调用doFilter()不放行,到不了servlet或者jsp

 

3.过滤器的各个方法的执行顺序

       1.构造方法

       2.初始化方法init(FilterConfig fConfig)

       3.doFilter()方法

       4.destroy()方法 销毁方法

4.FilterConfig接口的方法

       1.getFilterName():返回xml配置的filter的名字

       2.getInitParameter(name):返回初始化的参数的值

       3.getInitParameterNames():返回所有的初始化参数的名字

       4.getServletContext():返回上下文对象

5.FilterChain接口的方法

       1.doFilter()方法:

              1.如果有下一个过滤器就执行下一个过滤器

              2.没有就会执行目标资源(servlet或者jsp)

6.编码过滤器

       1.初始化参数encoding=UTF-8

       2.doFilter():设置encoding

三、过滤器的配置

(一)过滤器配置信息

  1.过滤器的名称和类

       2.过滤的url

       3.过滤的url的访问方式

              1.REQUEST:默认的访问方式

                     1.直接url访问

                     2.超级链接

                     3.form的提交

                     4.重定向

                     5.静态包含

              2.FORWARD请求转发

              3.INCLUDE动态包含

              4.ERROR错误页面的跳转

       4.初始化参数

       5.一个过滤器可以配置给多个url

       6.一个url可以配置多个过滤器,多个过滤器组成过滤器链,按照配置的顺序执行

 

范例:

<filter>
		<filter-name>MyFilter</filter-name>
		<filter-class>com.tjetc.filter.MyFilter</filter-class>
		<init-param>
			<param-name>name</param-name>
			<param-value>zs</param-value>
		</init-param>
</filter>
<filter-mapping>
		<filter-name>MyFilter</filter-name>
		<url-pattern>/order/*</url-pattern>
		<url-pattern>/cart/*</url-pattern>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>INCLUDE</dispatcher>
		<dispatcher>ERROR</dispatcher>
</filter-mapping>

(二)课堂练习

在filter-mapping的子节点dispatcher配置以何种方式访问url-pattern指定的资源能被过滤:REQUEST,FORWARD,请求和转发被过滤

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>HelloFilter</filter-name>
        <filter-class>com.tjetc.filter.HelloFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HelloFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
    <servlet>
        <servlet-name>Test1Servlet</servlet-name>
        <servlet-class>com.tjetc.servlet.Test1Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Test1Servlet</servlet-name>
        <url-pattern>/test1</url-pattern>
    </servlet-mapping>
</web-app>
package com.tjetc.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Test1Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Test1Servlet.doPost");
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
package com.tjetc.filter;
import javax.servlet.*;
import java.io.IOException;
public class HelloFilter implements Filter {
    public void destroy() { }
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            System.out.println("HelloFilter.doFilter()方法");
            chain.doFilter(req, resp);
    }
    public void init(FilterConfig config) throws ServletException {}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <base href="${pageContext.request.contextPath}/"/>
    <title>$Title$</title>
  </head>
  <body>
 这是首页
  </body>
</html>

HelloFilter.doFilter()方法

Test1Servlet.doPost

HelloFilter.doFilter()方法

一个工程有多个过滤器,形成过滤器链

多个过滤器的执行顺序是什么?

根据filter-mapping的url-pattern的顺序来执行

(三)课堂练习

验证多个过滤器的执行顺序是什么?

根据filter-mapping的url-pattern的顺序来执行.

一个工程里A B C 执行顺序是什么?

package com.tjetc.filter;
import javax.servlet.*;
import java.io.IOException;
public class AdeFilter implements Filter {
    public void destroy() {}
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("AdeFilter.doFilter");
        chain.doFilter(req, resp);
    }
    public void init(FilterConfig config) throws ServletException {}
}
package com.tjetc.filter;
import javax.servlet.*;
import java.io.IOException;
public class FdeFilter implements Filter {
    public void destroy() {}
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FdeFilter.doFilter");
        chain.doFilter(req, resp);
    }
    public void init(FilterConfig config) throws ServletException {}
}
package com.tjetc.filter;
import javax.servlet.*;
import java.io.IOException;
public class YdeFilter implements Filter {
    public void destroy() {}
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("YdeFilter.doFilter");
        chain.doFilter(req, resp);
    }
    public void init(FilterConfig config) throws ServletException {}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <filter>
        <filter-name>AdeFilter</filter-name>
        <filter-class>com.tjetc.filter.AdeFilter</filter-class>
    </filter>
    <filter>
        <filter-name>YdeFilter</filter-name>
        <filter-class>com.tjetc.filter.YdeFilter</filter-class>
    </filter>
    <filter>
        <filter-name>FdeFilter</filter-name>
        <filter-class>com.tjetc.filter.FdeFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FdeFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>YdeFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>AdeFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

FdeFilter.doFilter

YdeFilter.doFilter

AdeFilter.doFilter

四、利用过滤器实现访问控制

(一)什么是访问控制

有很多资源需要登录后才能访问,称为访问控制

访问控制使用过滤器实现效果更佳.

(二)登录过滤器实现访问控制

1.创建order.jsp订单页面

要访问order.jsp必须先登录才能访问,不登录不能访问

2.创建登录过滤器,过滤/order/*请求

判断用户是否登录,如果用户登录,用户信息会放到session

到session拿用户信息:

  • 如果用户信息不空代表用户已经登录,则放行
  • 如果用户信息为空,代表用户未登录,则重定向到登录页面,让用户去登录

3.创建login.jsp

4.创建LoginServlet

从请求参数取得用户名和密码

判断用户名和密码是否正确

  • 如果正确,将user放到session,session.setAttribute(“user”,user),重定向到jsp
  • 如果错误,重定向到jsp继续登录
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
        <base href="<%=request.getContextPath()%>/">
    </head>
    <body>
        <h1>order.jsp</h1>
    </body>
</html>
package com.tjetc.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        String username = (String) req.getSession().getAttribute("username");
        if (username == null) {
            resp.sendRedirect(req.getContextPath() + "/login.jsp");
        } else {
            //已登录,放行
            filterChain.doFilter(req, resp);
        }
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
        <base href="<%=request.getContextPath()%>/">
    </head>
    <body>
        <form action="login" method="post">
            用户名:<input type="text" name="username"><br>
            密码:<input type="password" name="password"><br>
            <input type="submit" value="登录">
            <%
                String msg = (String) request.getAttribute("msg");
                if (msg != null) {%>
            <span style="color:red"><%=msg%></span>
            <%
                }
            %>
        </form>
    </body>
</html>
package com.tjetc.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //登陆成功->订单页面(响应重定向订单url:/user/order)
        if ("hzw".equals(username) && "9588".equals(password)) {
            //存储用户信息
            req.getSession().setAttribute("username", username);
            resp.sendRedirect(req.getContextPath() + "/user/order");
        }
        //登陆失败->登录页面(错误消息)
        else {
            req.setAttribute("msg", "用户名或者密码错误");
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }
}

登录成功

登录失败

三、Servlet3.0新特性

(一)知识点1:注解

Servlet3.0注解有五种类型:

@WebServlet:对Servlet进行配置

@WebInitParam:配置Servlet初始化参数

@WebFilter:配置过滤器

@WebListener :配置监听器

@MultipartConfig:对文件上传的支持

 

1.@WebServlet:对Servlet进行配置

(1)必选属性

①value
  • value:等价于 urlPatterns 属性。
②urlPatterns
  • urlPatterns:等价于web.xml配置文件中的 <url-pattern> 标签

二者的值是一样的,而且代表的含义也是一样的.其他是可选的

③注意:

value和urlPatterns不能同时设置,只能使用其中的一个,同时设置就会报错

Caused by: java.lang.IllegalArgumentException: 类文件[com.tjetc.servlet.HelloServlet]的urlPatterns和值属性上同时设置了注解[WebServlet]

(2)可选属性

①name
  • 等价于web.xml配置文件中的 <servlet-name>。
1)如果没有指定name, Servlet 的<servlet-name>取值为类的全限定名,比如XXX.XXX.XXX。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 取得servlet的名字
    String servletName = getServletName();
    System.out.println(servletName);
    String servletName2 = getServletConfig().getServletName();
    System.out.println(servletName2);
    response.getWriter().append("Served at: ").append(request.getContextPath());
}

com.tjetc.servlet.HelloServlet

com.tjetc.servlet.HelloServlet

2)如果指定name,取值为指定的名字
@WebServlet(urlPatterns={"/HelloServlet","/abc"},name="HelloServlet")
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public HelloServlet() {super();  }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 取得servlet的名字
        String servletName = getServletName();
        System.out.println(servletName);
        String servletName2 = getServletConfig().getServletName();
        System.out.println(servletName2);
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }
}

HelloServlet

HelloServlet

②loadOnStartup:

等价于web.xml配置文件中的<load-on-startup> 标签

在服务器启动的时候就加载servlet,数字,越小代表越先启动

当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。

正数的值越小,该servlet的优先级越高,应用启动时就越先加载。

package com.tjetc.servlet;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns={"/HelloServlet","/abc"},name="HelloServlet",loadOnStartup=1)
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public HelloServlet() {
        super();
        System.out.println(" HelloServlet()...");
    }
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        System.out.println("init(ServletConfig config)...");
    }
    @Override
    public void init() throws ServletException {
        super.init();
        System.out.println("init()...");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 取得servlet的名字
        String servletName = getServletName();
        System.out.println(servletName);
        String servletName2 = getServletConfig().getServletName();
        System.out.println(servletName2);
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

五月 15, 2020 2:19:38 下午 org.apache.catalina.core.StandardEngine startInternal

信息: 正在启动 Servlet 引擎:[Apache Tomcat/9.0.34]

 HelloServlet()...

init()...

init(ServletConfig config)...

五月 15, 2020 2:19:39 下午 org.apache.coyote.AbstractProtocol start

信息: 开始协议处理句柄["http-nio-8080"]

五月 15, 2020 2:19:39 下午 org.apache.catalina.startup.Catalina start

信息: Server startup in [737] milliseconds

HelloServlet

HelloServlet

③initParams :
  • 等价于web.xml配置文件中的<init-param> 标签,他的参数是@WebInitParam注解的集合
④description:
  • 等价于web.xml配置文件中的<description> 标签
⑤displayName:
  • 等价于web.xml配置文件中的 <display-name> 标签

2.@WebInitParam:

配置Servlet初始化参数,常用属性有三个,这三个属性当中只有description为可选属性:

name:等价于web.xml配置文件中的 <param-name>

value :等价于web.xml配置文件中的<param-value>

description:等价于web.xml配置文件中的<description>

package com.tjetc.servlet;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns={"/HelloServlet","/abc"},name="HelloServlet",
            initParams={@WebInitParam(name="name",value="zs")})
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public HelloServlet() {
        super();
        System.out.println(" HelloServlet()...");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //取得初始化参数的值
        String name = getInitParameter("name");
        System.out.println(name);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

zs

3.@WebFilter:

  • 配置过滤器此注解为声明一个过滤器,主要属性有以下几个。

(1)value、urlPatterns、servletNames至少包含一个

在这些属性当中value、urlPatterns、servletNames 三个属性至少要包含其中的一个,并且 value 和 urlPatterns 属性只能有一个,如果两个同时配置,一般情况下value取值将会被忽略。

①value:该属性等价于 urlPatterns 属性
②urlPatterns:等价于web.xml配置文件中的 <url-pattern> 标签
③servletNames:

指定该过滤器将应用的范围。如果是注解的话取值是 @WebServlet 中的 name 属性的取值,如果servlet在 web.xml 中配置的话,取值是 <servlet-name> 的取值

(2)其他的都是可选属性

filterName:等价于web.xml配置文件中的 <filter-name>标签,过滤器的名称

dispatcherTypes:过滤器的转发模式。取值包括:

ASYNC(异步)、ERROR(错误)、FORWARD(请求转发)、INCLUDE(包含)、REQUEST(请求)。

initParams:等价于web.xml配置文件中的<init-param> 标签

description:等价于web.xml配置文件中的<description> 标签

displayName:等价于web.xml配置文件中的<display-name> 标签

package com.tjetc.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.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
@WebFilter(servletNames="HelloServlet",filterName="MyFilter",initParams={@WebInitParam(name="company",value="zhongruan")})
public class MyFilter implements Filter {
    public MyFilter() {}
    public void destroy() {}
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("MyFilter.doFilter()...");
        chain.doFilter(request, response);
    }
    public void init(FilterConfig fConfig) throws ServletException {
        String filterName = fConfig.getFilterName();
        System.out.println("filterName="+filterName);
        String company = fConfig.getInitParameter("company");
        System.out.println(company);
    }
}

信息: 正在启动 Servlet 引擎:[Apache Tomcat/9.0.34]

filterName=MyFilter

zhongruan

PrintServlet()

五月 15, 2020 3:18:15 下午 org.apache.coyote.AbstractProtocol start

信息: 开始协议处理句柄["http-nio-8080"]

五月 15, 2020 3:18:15 下午 org.apache.catalina.startup.Catalina start

信息: Server startup in [778] milliseconds

 HelloServlet()...

init()...

init(ServletConfig config)...

MyFilter.doFilter()...

zs

(3)课堂练习

①目标

使用注解配置一个过滤器

②步骤
1)创建一个过滤器,写注解@WebFilter
2)写属性
package com.tjetc.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.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
@WebFilter(servletNames="HelloServlet",filterName="MyFilter",initParams={@WebInitParam(name="company",value="zhongruan")})
public class MyFilter implements Filter {
    public MyFilter() {}
    public void destroy() {}
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("MyFilter.doFilter()...");
        chain.doFilter(request, response);
    }
    public void init(FilterConfig fConfig) throws ServletException {
        String filterName = fConfig.getFilterName();
        System.out.println("filterName="+filterName);
        String company = fConfig.getInitParameter("company");
        System.out.println(company);
    }
}

信息: 正在启动 Servlet 引擎:[Apache Tomcat/9.0.34]

filterName=MyFilter

zhongruan

PrintServlet()

五月 15, 2020 3:18:15 下午 org.apache.coyote.AbstractProtocol start

信息: 开始协议处理句柄["http-nio-8080"]

五月 15, 2020 3:18:15 下午 org.apache.catalina.startup.Catalina start

信息: Server startup in [778] milliseconds

 HelloServlet()...

init()...

init(ServletConfig config)...

MyFilter.doFilter()...

zs

4.@WebListener:配置监听器,

此注解是用来声明监听器,它主要的属性只有一个:

value:这个属性表示的是监听器的描述信息,整个配置可以简写成@WebListener("XXX")

@WebListener
public class MyListener implements ServletContextListener{
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("contextInitialized()...");
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        ServletContextListener.super.contextDestroyed(sce);
    }
}

contextInitialized()...

(二)知识点2:文件上传

  • 1.创建项目,版本选择3.0及其以上
  • 2.add.jsp:form:method=”post” enctype=”multipart/form-data”
  • 3.Servlet添加@MultipartConfig,servlet开启对上传文件的支持
    • a)fileSizeThreshold:当数据量大于该值时,内容将被写入文件。
    • b)maxFileSize:允许上传的文件最大值。默认值为 -1,表示没有限制。
    • c)maxRequestSize:针对该 multipart/form-data 请求的最大数量,默认值为 -1,表示没有限制。
  • 4.doPost()
    • a)设置请求编码:request.setCharacterEncoding(“UTF-8”);
    • b)取得普通表单的参数的值:request.getParameter(name);
    • c)Part part=request.getPart(“photo”);
    • d)判断是否上传文件:if(part!=null && part.getSize()>0){
      • i.文件名:String filename=part.getSubmmitedFileName();
      • ii.上传路径:String realPath=request.getServletContext().getRealPath(“/upload/”);File dir=new File(realPath);If(!dir.exists()){ Dir.mkdirs();}
      • iii.写文件:Part.write(realPath+”/”+filename);

@MultipartConfig

                     1.location:存放路径

                     2.maxFileSize:上传文件的最大尺寸,默认值为 -1,表示没有限制。

                     3.maxReqesutSize:请求的最大尺寸,默认值为 -1,表示没有限制。

                     4.fileSizeThreshold:当内容超过该值,内容就被写到文件,默认值是0

package com.tjetc.servlet;
import java.io.File;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
/**
 * Servlet implementation class UploadServlet
 */
@WebServlet("/UploadServlet")
@MultipartConfig//@MultipartConfig,servlet开启对上传文件的支持
public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    /**
    * @see HttpServlet#HttpServlet()*/
    public UploadServlet() {
        super();
    }
    /**
    * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
    */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置请求编码
        request.setCharacterEncoding("UTF-8");
        //取得普通表单字段的值
        String name = request.getParameter("name");
        //取得part对象
        Part part = request.getPart("photo");
        //判断是否为空
        if (null!=part&& part.getSize()>0) {//处理上传
            //取得上传的文件名
            String fileName = part.getSubmittedFileName();//上传文件的存放路径/upload/
            String realPath = request.getServletContext().getRealPath("/upload/");
            System.out.println(realPath);
            //创建file对象 
            File dir = new File(realPath);
            //判断/upoad是否存在
            if (!dir.exists()) {//不存在upload文件夹就创建该文件夹
                dir.mkdirs();//创建该文件夹
            }
            //实现复制文件
            part.write(realPath+"/"+fileName);
            part.write(fileName);
            //上传完毕
            response.getWriter().print("upload ok!...");
        }
    }
    /**
    * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

 

posted @   carat9588  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示