Filter
当用户访问服务器资源时,过滤器将请求拦截下来,完成一些通用的操作。
快速入门之.xml配置实现
编写java类,实现Filter接口
/**
* @author lifly
* @date 2021/6/20 0020 20:49
*/
public class QuickFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 该方法拦截用户请求
* @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("quickFilter拦截了请求。。。");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
web.xml配置
<!-- 快速入门-->
<!-- 注册filter-->
<filter>
<filter-name>QuickFilter</filter-name>
<filter-class>com.lifly.filter.QuickFilter</filter-class>
</filter>
<!-- 配置filter拦截路径-->
<filter-mapping>
<filter-name>QuickFilter</filter-name>
<url-pattern>/quick.jsp</url-pattern>
</filter-mapping>
快速入门之注解实现
/**
* @author lifly
* @date 2021/6/20 0020 20:58
*/
//@WebFilter("/annotationFilter.jsp")//精准匹配
//@WebFilter("/filter/*")//目录匹配
//@WebFilter("*.html")//后缀匹配
@WebFilter("/*")//匹配所有
public class AnnotationFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("注解配置过滤器");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
Filter的声明周期
init服务器启动项目加载,创建filter,执行init方法(只执行一次)
doFilter用户访问被拦截目标资源时,执行doFilter方法,执行多次
destory服务器关闭前,Filter对象被销毁。如果服务器是正常关闭,则会执行destory方法,只执行一次。
过滤器一定是优先于Servlet创建的
拦截路径
- 精准匹配
用户访问制定目标资源例如(/index.jsp)时,过滤器进行拦截- 目录匹配
用户访问指定目录下例如(/user/*)所有资源时,过滤器进行拦截- 后缀匹配
用户访问指定后缀名(.html)的资源时,过滤器进行拦截
4.匹配所有
用户访问该网站所有资源(/)时,过滤器进行拦截
//@WebFilter("/annotationFilter.jsp")//精准匹配
//@WebFilter("/filter/*")//目录匹配
//@WebFilter("*.html")//后缀匹配
@WebFilter("/*")//匹配所有
过滤器链
在一次请求中,请求匹配到多个filter,通过请求就相当于把这些filter串起来,形成了过滤器连
需求
用户访问目标路径show.jsp时,经过FilterA,FilterB
过滤器执行链执行顺序(先进后出)
- 用户发送请求
- FilterA拦截,放行
- FilterB拦截,放行
- 执行目标资源show.jsp
- FilterB增强响应
- FilterA增强响应
- 封装响应响应格式,返回到浏览器
代码演示
- show.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>过滤器链</h3>
</body>
</html>
- FilterA.java
/**
* @Describe
* @Author Double LiFly
* @date 2021/6/21 10:18
*/
@WebFilter("/show.jsp")
public class FilterA implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filterA拦截。。。");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("filterA放行");
}
@Override
public void destroy() {
}
}
- FilterB.java
/**
* @Describe
* @Author Double LiFly
* @date 2021/6/21 10:19
*/
@WebFilter("/show.jsp")
public class FilterB implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filterB拦截。。。");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("filterB放行");
}
@Override
public void destroy() {
}
}
Listener
在java程序中,有时候需要监视某些事情,一旦被监视的对象发生相应的变化,执行相应的操作。
例如:使用于历史访问次数,统计在线人数,系统启动初始化配置信息
作用
- 监听作用域对象的创建和销毁
ServletRequestListener:监听请求对象的创建和销毁
HttpSessionListener:监听会话对象(session)的创建和销毁
ServletContextListener:监听应用的创建和销毁- 监听作用域对象的属性的添加,删除,替换
快速实现
实现步骤
定义一个类,实现ServletContextListener接口
重写接口中的抽象方法
配置监听器
实现
/**
* @Describe
* @Author Double LiFly
* @date 2021/6/21 14:07
*/
public class ListenerDemo01 implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContextListener创建了");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContextListener销毁了");
}
}
//监听器配置
<listener>
<listener-class>com.lifly.listener.ListenerDemo01</listener-class>
</listener>
统计网站在线人数
有用户使用网站,在线人数就+1;用户退出在线人数就减1
代码演示
- index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
在线人数: ${number}
<br>
<a href="/logoutServlet">退出系统</a>
</body>
</html>
- InitNumberListener.java
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
在线人数: ${number}
<br>
<a href="/logoutServlet">退出系统</a>
</body>
</html>
- NumberChangeListener.java
/**
* @Describe
* @Author Double LiFly
* @date 2021/6/21 14:12
*/
@WebListener
public class NumberChangeListener implements HttpSessionListener {
/**
* session创建
* @param httpSessionEvent
*/
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
int number = (int) servletContext.getAttribute("number");
servletContext.setAttribute("number",number+1);
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
int number = (int) servletContext.getAttribute("number");
servletContext.setAttribute("number",number-1);
}
}
- logoutServlet.java
@WebServlet("/logoutServlet")
public class LogoutServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 处理post请求乱码问题
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//销毁
request.getSession().invalidate();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}