1、过滤器Filter
1.1、Filter概念
过滤器: 过筛子,符合条件的过去,不符合条件不能过去.
生活比喻: 安检,检查安全的人与物才可以通过放行
程序: 客户端需要访问服务器的目标资源,在客户端和服务器资源之间设置过滤器, 符合要求放行
1.2、Filter的入门程序
需求:
●浏览器要访问Servlet
●途径过滤期Filter, 若Filter放行,可执行访问到Servlet; 若不放行,无法访问Servlet
执行图解:
实现步骤
- 编写Servlet, 在web.xml配置Servlet访问路径
- 编写Filter,定义类, 实现接口Filter, 实现接口中抽象方法, 在web.xml配置Filter的访问过滤路径
代码:Servlet
package com.bdit;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = {"/hello2"})
public class HelloServlet 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 {
System.out.println("====================HelloServlet===============");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().print("<p>经过过滤器到达类HelloServlet</p>");
}
}
代码:Filter
package com.bdit;
import javax.servlet.*;
import java.io.IOException;
public class HelloFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("=========请求到达过滤器=======");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("============响应到达过滤器===========");
}
}
代码: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>helloServlet</servlet-name>
<servlet-class>com.bdit.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!--配置过滤器-->
<filter>
<filter-name>helloFilter</filter-name>
<filter-class>com.bdit.HelloFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>helloFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--如果有两个过滤器按照配置顺序执行-->
<filter>
<filter-name>helloFilter2</filter-name>
<filter-class>com.bdit.HelloFilter2</filter-class>
</filter>
<filter-mapping>
<filter-name>helloFilter2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
1.3、Filter的生命周期
●过滤器对象的创建,是Tomcat服务器启动(而Servlet默认是第一个请求到达时)
○init(FilterConfig config)过滤器对象被创建的时候调用,FilterConfig 对象tomcat引擎创建
●过滤器执行过滤的方法,过滤被访问资源的时候,必须是被过滤器过滤器的资源
○doFilter(request,response)
●过滤器对象销毁的方法,销毁之前调用,服务器关闭
○destroy()
1.4、Filter的url-pattern配置
完全匹配:
<!--
过滤资源,只有hello
绝对匹配<url-pattern>/hello</url-pattern>
只能过滤指定的资源
-->
<url-pattern>/hello</url-pattern>
目录匹配:
<!--
目录匹配,过滤器中最常见
/abc/* 过滤abc目录下的所有资源
一次过滤一片资源
过滤后台资源/admin/*
-->
<url-pattern>/admin/*</url-pattern>
后缀名匹配:
<!--
后缀名匹配,一般不使用
*.jsp 访问所有jsp文件
-->
<url-pattern>*.jsp</url-pattern>
1.5、注解配置Filter
@WebFilter(urlPatterns="/过滤资源")
@WebFilter("/*")
public class ChinaFilter implements Filter{
//代码省略...
}
1.6、Filter处理中文乱码
需求:使用过滤器Filter, 处理所有请求的中文乱码
代码:Filter
package com.bdit.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter(urlPatterns = {"/safe/*"})
public class TreeFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("UTF-8");
servletResponse.setContentType("test/html;charset=UTF-8");
filterChain.doFilter(request,response);
}
}
1.7、过滤器链FilterChain的执行过程
Filter中的过滤器链 FilterChain:由Tomcat引擎创建对象
作用:维护过滤器执行顺序
小结: Servlet中doGet方法参数 request, response对象, 由Tomcat引擎创建, 经过多个过滤器一层层传递
1.8、多个过滤器的先后执行顺序
web.xml配置
和配置文件的编写顺序决定运行的顺序,准确的说法是,根据mapping的顺序决定 (由上到下执行)
注解开发
注解开发没有配置文件的
按照类名的自然顺序决定: A-B-C
如果存在配置文件,配置文件优先
2、监听器Listener
2.1、Listener概述
监听器Listener 是监听某个组件变化的对象.
事件源是固定的,主要是request, session, servletcontext域对象
监听的是域对象变化
●对象的创建和销毁, 域对象中存储的数据变化
第一个维度划分:
●监听的域对象request, session, servletcontext
域对象 | 监听器 |
---|---|
request | ServletRequestListener |
session | HttpSessionListener |
servletcontext | ServletContextListener |
第二个维度划分:
●监听的域对象的状态
2.2、 ServletContext监听器入门
用于监听 servletcontext域对象, 对象的创建和销毁, 域对象中存储的数据变化
实现步骤
●创建类实现监听器接口 ServletContextListener
●重写抽象方法
●注解方式配置 Listener
package com.bdit.liternce;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebServlet;
//监听器
@WebListener
public class ListernceServlet implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext域对象创建");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext域对象销毁");
}
}
web.xml配置方式 Listener
<!--监视器-->
<listener>
<listener-class>com.bdit.liternce.ListernceServlet</listener-class>
</listener>
2.3、监听器事件对象ServletContextEvent
ServletContextEvent: 是ServletContext域对象的事件对象, 此对象由tomcat引擎创建ServletContext
方法:
●ObjectgetSource()获取到被监听的事件源
●ServletContextgetServletContext()获取到被监听的事件源
小结:
●两个方法除了返回值外,功能实现是一致的, 设计目的为了通用性
●其他的监听器事件对象(HttpSessionEvent, ServletRequestEvent), 都有共同的方法getSource()
package com.bdit.liternce;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
//监听器
@WebListener
public class ListernceServlet implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent ) {
System.out.println("ServletContext域对象创建");
ServletContext context = (ServletContext) servletContextEvent.getSource();
System.out.println(context);
ServletContext servletContext = servletContextEvent.getServletContext();
System.out.println(servletContext);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent ) {
System.out.println("ServletContext域对象销毁");
}
}
2.4、注解版
package com.bdit.liternce;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
//每次请求都会创建一个新的request对象;当响应结束后,立刻销毁request对象
@WebListener
public class ListernceServlet implements ServletContextListener {
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
ServletRequest servletRequest = servletRequestEvent.getServletRequest();
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
System.out.println("新的request对象创建了.......路径:" + httpServletRequest.getRequestURI());
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("request对象销毁了.......");
}
}