目录
一、过滤器【重点】
1.1 现有问题
在以往的Servlet中,有没有冗余的代码,多个Servlet都要进行编写。
例如:每个JSP文件中都要验证是否登录
<body>
<%
Object user = session.getAttribute("user");
// 如果 user = null; 说明 user 还没有登陆
if (user == null) {
request.getRequestDispatcher("/login.jsp").forward(request,response);
return; // 一般请求转发后,就不允许再执行任何代码,这里就直接return了
}
%>
登录成功
</body>
1.2 概念
过滤器 (Filter) 是处于客户端与服务器目标资源之间的一道过滤技术。
Filter 过滤器它是 JavaWeb 的三大组件之一。
三大组件分别是:Servlet 程序、Listener 监听器、Filter 过滤器
1.3 过滤器作用
执行地位在Servlet之前,客户端发送请求时,会先经过Filter,再到达目标Servlet中;响应时,会根据执行流程再次反向执行Eilter
可以解决多个Servlet共性代码的冗余问题 (例如:乱码处理、登录验证)
1.4 编写过滤器
Servlet API中提供了一个Filter接口,开发人员编写一个Java类实现了这个接口即可,这个Java类称之为过滤器 (Filter)
1.4.1 实现过程
编写Java类实现Filter接口
在doFilter方法中编写拦截逻辑
设置拦截路径
1.4.2 要求
要求:在你的web工程下,有一个admin目录。这个admin目录下的所有资源(html 页面、jpg图片、jsp文件、...)都必须是用户登录之后才允许访问。
package com.ha.filter;
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
/*
* 获取user:
* HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
* HttpSession session = httpServletRequest.getSession();
* Object user = session.getAttribute("user");
*/
String user = "HuAn";
// 如果 user = null; 说明 user 还没有登陆
if (user == null) {
/*
* 执行跳转窗口命令:
* httpServletRequest.getRequestDispatcher("/login.jsp").forward(httpServletRequest,servletResponse);
*/
return; // 一般请求转发后,就不允许再执行任何代码,这里就直接return了
} else {
// 让程序继续往下访问用户的目标资源
filterChain.doFilter(servletRequest,servletResponse);
}
}
public void destroy() {
}
}
<?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_3_1.xsd"
version="3.1"
metadata-complete="true">
<filter>
<filter-name>t</filter-name>
<filter-class>com.ha.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>t</filter-name>
<!--配置拦截路径
/ 表示请求地址为: http://ip:port/工程路径/ 映射到 IDEA 的 web 目录
/admin/* 表示请求地址为 http://ip:port/工程路径/admin/* (admin 下的全部)
-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
</web-app>
运行结果:
如果:
则:
如果:
则:
1.5 过滤器链和优先级
1.5.1 过滤器链
客户端对服务器请求之后,服务器调用Servlet之前会执行一组过滤器(多 个过滤器),那么这组过 滤器就称为一条过滤器链。
每个过滤器实现某个特定的功能,当第一个Filter的doFilter方法被调用时,Web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则Web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。
1.5.2 过滤器优先级
在一个Web应用中, 可以开发编写多个Filter,这些Filter组 合起来称之为-个Filter链。
优先级:
如果为注解的话,是按照类全名称的字符串顺序决定作用顺序
如果web.xml, 按照 filter-mapping 注册顺序, 从上往下
web.xml 配置高于注解方式
如果注解和 web.xm 同时配置, 会创建多个过滤器对象,造成过滤多次。
1.5.3 关于拦截路径
过滤器的拦截路径通常有三种形式:
精确拦截匹配,比如/index.jsp /myservlet
后缀拦截匹配,比如*. jsp、*.html、*.jpg
通配符拦截匹配/*,表示拦截所有。注意过滤器不能使用 / 匹配。/aaa/bbb/*允许
1.6 常用应用
1、统一编码
2、权限控制,登录验证等