Servlet、Filter、Listener为JavaWeb的三大组件
文章目录
一、Filter:过滤器
1.1 概念
- web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。
- 过滤器的作用:一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤。
1.2 快速入门
-
步骤:
- 定义一个类,实现
Filter接口
- 复写方法
- 配置要拦截的路径(两种配置方法)
-
方法一:配置web.xml文件
方法二:注解配置。@WebFilter(value="/*")
里面为要拦截的路径
-
方法一:配置web.xml文件
- 定义一个类,实现
1.3 过滤器细节
1.3.1 web.xml配置(和Servlet差不多一样)
<filter>
<filter-name>FileDemo</filter-name>
<filter-class>cn.itcast.web.filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
<!-- 映射名称 -->
<filter-name>FileDemo</filter-name>
<!-- 拦截路径 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
1.3.2 过滤器执行流程
- tomcat引擎将客户端浏览器的http请求转成request对象,http响应转response对象
- 地址符合过滤的条件,则将request,resposne传给过滤器的doFilter方法
- 执行chain.doFilter(request,response)方法前的代码(对请求消息增强),并且传给该方法进行放行
- 再传给Serclet对象的doGet或者doPost方法,进行对response响应对象进行设置,或者调用相应的资源
- doFilter再执行剩余代码之后(对reponse进行增强),reponse再返回浏览器 设置编码的代码位置
doFilter之前设置增强请求编码,之后设置增强响应编码
1.3.3 过滤器生命周期方法(Filter接口中的方法)
init方法
:在服务器启动后,会创建Filter
对象,然后调用init
方法。只执行一次。用于加载资源。doFilter方法
:每一次请求被拦截资源时,会执行。执行多次。(里面的两个形参都是Servlet对象,一般都转化为HttpServlet对象在使用)destroy方法
:在服务器关闭后,Filter
对象被销毁。如果服务器是正常关闭,则会执行该方法。只执行一次。用于释放资源。
1.3.4 过滤器配置详解
- 拦截路径的配置
- 具体资源路径:
/index.jsp
,只有访问index.jsp
,过滤器才会被执行。 - 目录拦截:
/user/*
,访问/user
下的所有资源时,过滤器都会被执行 - 后缀名拦截:
*.jsp
,访问所有后缀名为jsp的资源时,过滤器都会被执行。 - 拦截所有资源:
/*
,访问所有资源时,过滤器都会被执行
- 具体资源路径:
- 拦截方式的配置:资源被访问的方式
- 注解配置
-
设置
注解的dispatcherType属性
:@WebFilter(value="/index.jsp", dispatcherTypes = {DispatcherType.FORWARD, DispatcherType.REQUEST})
可拦截多种方式,dispatcherTypes属性
中以数组形式保存,有5个可选值 :REQUEST
:默认值。浏览器直接请求资源时,过滤器才会被执行FORWARD
:转发访问资源时,过滤器才会被执行INCLUDE
:包含访问资源时,过滤器才会被执行ERROR
:错误跳转资源时,过滤器才会被执行ASYNC
:异步访问资源时,过滤器才会被执行
-
设置
- web.xml配置
-
设置
<dispatcher></dispatcher>
标签,同上5个值
-
设置
- 注解配置
1.3.5 过滤器链(配置多个过滤器)
- 执行顺序:如果有两个过滤器:过滤器1和过滤器2
- 过滤器1
- 过滤器2
- 资源执行
- 过滤器2
- 过滤器1
- 过滤器的先后顺序问题:
- 注解配置:按照类名的字符串比较规则,值小的先执行
-
如:
AFilter
和BFilter
,A小,先执行
-
如:
- web.xml:
<filter-mapping></filter-mapping>
谁映射定义在上面,谁先执行
- 注解配置:按照类名的字符串比较规则,值小的先执行
二、Listener:监听器
2.1 概念
- web的三大组件之一
- 事件监听机制
- 事件:一件事情
- 事件源:事件发生的地方
- 监听器:一个对象
- 注册监听:将事件、事件源、监听器绑定在一起。当事件源上发生某个事件后,执行监听器代码
- 事件监听机制
2.2 ServletContextListener监听器接口
-
方法
void contextInitialized(ServletContextEvent sce)
:服务器启动之后,监听器对象ServletContext
创建会调用该方法。void contextDestroyed(ServletContextEvent sce)
:服务器正常关闭,监听器对象ServletContext
被销毁时会调用该方法。
-
步骤:
-
定义一个类,实现
ServletContextListener
接口 -
实现接口的方法
-
配置
-
web.xml
<!-- 注册监听器--> <listener> <listener-class>cn.itcast.web.listener.ContextLoaderListener</listener-class> </listener>
-
注解:
@WebListener
-
-
- 指定初始化参数
<!-- 指定初始化的参数信息-->
<context-param>
<param-name>contextFigLocation</param-name>
<param-value></param-value>
</context-param>
@WebListener()
public class ListenerText1 implements ServletContextListener{
/*
Tomcat服务器启动的时候,监听器对象创建的时候会执行该方法
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
//加载临时文件
//1获取ServletContext对象
ServletContext servletContext = sce.getServletContext();
//2加载资源文件
String contextConfigLocation = servletContext.getInitParameter("applicationContext");
//3获取真实路径
String realPath = servletContext.getRealPath(contextConfigLocation);
//4加载进内存
try {
FileInputStream fis = new FileInputStream(realPath);
System.out.println(fis);
}catch (Exception e){
e.printStackTrace();
}
}
/*
Tomcat服务器正常关闭的时候,会执行该方法
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
过滤器案例
案例1:登录验证
- 要求:
- 访问该项目下资源,都要判断是否登入
- 如果登入了直接放行
- 如果没登入,跳转到登入界面,提示:您尚未登入,请登入
//对所有资源的都进行过滤
@WebFilter("/*")
public class 登录验证 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//1强制转换类型
HttpServletRequest request = (HttpServletRequest) servletRequest;
//2获取资源请求路径
String uri = request.getRequestURI();
//3判断请求路径是否包含登入相关的资源的路径(排出掉登入需要的css jsp js 图片 验证码等等)
if(uri.contains("/login.jsp") || uri.contains("/css/") || uri.contains("/js/")){
//3.1包含登入相关的的资源--放行
filterChain.doFilter(servletRequest,servletResponse);
}else{
//3.2不包含登入相关的资源
//3.2.1判断是否登入了(在请求信息中是否包含用户的信息)
Object user = request.getSession().getAttribute("user");
if(user!=null){
//登入了--放行
filterChain.doFilter(servletRequest,servletResponse);
}else{
//未登入
//把未登入的信息保存下来,方便使用
request.setAttribute("mfg","您尚未登入,请登入");
//跳转到登入界面(进行转发)
request.getRequestDispatcher("/login.jsp").forward(request,servletResponse);
}
}
}
@Override
public void destroy() {
}
}