步骤:
每个 Filter 过滤器会拦截访问指定目录下资源的请求,可以在拦截时进行权限检查等操作。
需求:
admin 文件夹下的 1.jpg,只有登录的用户才可以访问,编写 Filter 程序,拦截所有访问 1.jpg 的请求,只有登录的用户才放开请求,未登录的用户强制跳转到登录页面。
判断用户是否登录:
用户登录成功后,会把用户的登录信息保存到 Session 域中,因此,要检查用户是否登录,可以判断 Session 中是否保存了用户的登录信息即可。
在地址栏输入:http://localhost:8080/Filter/admin/1.jpg
AdminFilter.java
package myFilter;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class AdminFilter implements Filter{
/**
* doFilter方法,专门用于拦截请求,可以做权限检查
*/
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)arg0;
Object userInfo = req.getSession().getAttribute("userInfo");
//userInfo为空代表没有登录,不能访问admin文件夹下的文件
if(userInfo==null) {
//返回首页
req.getRequestDispatcher("/login.jsp").forward(arg0, arg1);
} else {
//已经登录,放开拦截,可以访问admin下的文件
arg2.doFilter(arg0, arg1);
}
}
}
配置 AdminFilter 要拦截的路径
web.xml
<filter>
<filter-name>AdminFilterfilter-name>
<filter-class>myFilter.AdminFilterfilter-class>
filter>
<filter-mapping>
<filter-name>AdminFilterfilter-name>
<url-pattern>/admin/*url-pattern>
filter-mapping>
登录页面
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="http://localhost:8080/Filter/loginServlet" method="get">
用户名:<input type="text" name="username"/> <br>
密 码:<input type="password" name="password"/> <br>
<input type="submit" />
</form>
</body>
</html>
LoginServlet 接收登录请求
LoginServlet.java
package myServlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=UTF-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
if("admin".equals(username) && "admin".equals(password)) {
req.getSession().setAttribute("userInfo", username);
resp.getWriter().write("登录成功");
} else {
req.getRequestDispatcher("/login.jsp").forward(req, resp);
}
}
}
配置 LoginServlet 的访问路径
<servlet>
<servlet-name>LoginServletservlet-name>
<servlet-class>myServlet.LoginServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>LoginServletservlet-name>
<url-pattern>/loginServleturl-pattern>
servlet-mapping>
Filter 的生命周期包含以下几个方法:
FilterConfig 类,是 Filter 过滤器的配置文件类。
Tomcat 每次创建 Filter 时,会同时创建一个 FilterConfig 类,类内包含了 Filter 配置文件的配置信息。
FilterConfig 类的作用:
web.xml
<!-- 配置AdminFilter -->
<!--filter 标签用于配置一个 Filter 过滤器-->
<filter>
<!--给 filter 起一个别名-->
<filter-name>AdminFilter</filter-name>
<!--配置 filter 的全类名-->
<filter-class>myFilter.AdminFilter</filter-class>
<!-- 配置初始化参数 -->
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost3306/test</param-value>
</init-param>
</filter>
<!--filter-mapping 配置 Filter 过滤器要拦截的路径-->
<filter-mapping>
<!--filter-name 表示当前的拦截路径给哪个 filter 使用-->
<filter-name>AdminFilter</filter-name>
<!--url-pattern 配置拦截路径
/ 表示请求地址为:http://ip:port/工程路径/ 映射到工程的 web 目录
/admin/* 表示请求地址为:http://ip:port/工程路径/admin/*,其中*表示该文件夹下的全部文件
-->
/admin/*
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//FilterConfig 类的作用是获取 filter 过滤器的配置内容
//1、获取 Filter 的名称,即 filter-name 的内容
String filterName = filterConfig.getFilterName();
System.out.println(filterName);
//2、获取在 Filter 中配置的 init-param 初始化参数
String username = filterConfig.getInitParameter("username");
System.out.println(username);
//3、获取 ServletContext 对象
ServletContext servletContext = filterConfig.getServletContext();
System.out.println(servletContext);
}
FilterChain 类,是过滤器链,即多个过滤器如何一起工作。
多个 Filter 执行时的特点:
/target.jsp
/admin/*
*.xyz
表示请求地址以 .xyz 结尾时,发生拦截。Filter 过滤器只关心请求的地址是否匹配,不关心请求的资源是否存在,即使资源不存在,但地址匹配,也会发生拦截。