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))
- 上下文事件ServletContextEvent 上下文对象发生改变
- 请求相关事件
- 请求事件ServletReqeustEvent 请求对象发生改变
- 创建(请求servlet)
- 销毁(返回响应过程结束)
- 请求属性事件ServletReqeustAttributeEvent 请求属性发生改变 添加、删除、覆盖属性
- 请求事件ServletReqeustEvent 请求对象发生改变
- 会话相关事件
- 会话事件HttpSessionEvent 会话对象发生改变
- 创建(request.getSession(true))
- 销毁(30分钟 50分钟 invalidate() setMaxInactiveInterval(秒))
- 活化 反序列化 从磁盘取出反序列化到内存得到会话对象
- 钝化 序列化 把会话对象序列化到磁盘
- 会话绑定事件HttpSessionBindingEvent 会话属性发生改变 添加、删除、覆盖属性
- 会话事件HttpSessionEvent 会话对象发生改变
- 上下文相关事件
2.监听器接口
监听器接口定义了监听事件的方法
Servlet API中定义了8种监听器接口,用来监听不同的事件类型
上下文相关的监听器
-
①上下文监听器ServletContextListener,监听上下文事件ServletContextEvent
-
②上下文属性监听器ServletContextAttributeListener,监听ServletContextAttributeEvent上下文属性事件
请求相关的监听器
-
①请求监听器ServletRequestListener,监听请求事件ServletRequestEvent
-
②请求属性监听器ServletRequestAttributeListener,监听请求属性事件ServletRequestAttributeEvent
会话相关的监听器
-
①会话监听器HttpSessionListener,监听会话事件HttpSessionEvent
-
②会话活化监听器HttpSessionActivationListener,监听会话事件HttpSessionEvent
-
③会话属性监听器HttpSessionAttributeListener,监听会话绑定事件HttpSessionBindingEvent
-
④会话绑定监听器 HttpSessionBindingListener,监听会话绑定事件HttpSessionBindingEvent
(三)知识点3:监听器的开发与配置
ServletContextListener
- 写一个类实现XXXListener接口
- 重写接口中的方法,实现监听的功能
- 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
- 写一个类实现XXXListener接口
- 重写接口中的方法,实现监听的功能
- 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>
思路:
- 写一个类实现HttpSessionAttributeListener接口
- 重写接口的方法
- 写servlet,向session添加属性,覆盖属性,移除属性
- 启动服务器,访问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))
- 会话事件HttpSessionEvent 会话对象发生改变
- 上下文相关事件
- 监听器接口(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测试.
- 放行 执行doFilter(request,response)
- 不放行 不执行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);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话