Filter过滤器
什么是Filater过滤器
Filter过滤器的基本使用介绍
-
以权限检查来演示
但是,只有jsp文件中可以访问session域,那其他的资源,如:html文件,图片该怎样阻止访问呢? -
Filter过滤器原理
**注意导入的是javax.servlet
包下面的Filter接口 -
过滤器:AdminFilter
package com.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.http.HttpRequest;
public class AdminFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
//doFilter 方法,专门用于拦截请求。可以做权限检查
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpSession session = httpServletRequest.getSession();
if(session.getAttribute("user")==null){
/*请求转发到Login.jsp页面进行登录*/
servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);
return;
}else {
filterChain.doFilter(servletRequest,servletResponse);
}
}
@Override
public void destroy() {
}
}
- Filter配置信息
<filter>
<!--给filter起一个别名-->
<filter-name>AdminFilter</filter-name>
<!--配置filter的全类名-->
<filter-class>com.filter.AdminFilter</filter-class>
</filter>
<!--filter-mapping 配置 Filter 过滤器的拦截路径-->
<filter-mapping>
<!--filter-name 表示当前的拦截路径给哪个 filter 使用-->
<filter-name>AdminFilter</filter-name>
<!--url-pattern 配置拦截路径
/ 表示请求地址为:http://ip:port/工程路径/ 映射到 IDEA 的 web 目录
/admin/* 表示请求地址为:http://ip:port/工程路径/admin/*
表示admin目录下面所有文件都进行拦截
-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
在有些情况下我们的过滤图片可能会失效,这是因为浏览器缓存优化的问题(在前面也遇到过)。即并没有访问服务器而是直接访问了缓存
解决方案
- 1.清理浏览器的缓存
- 2.在请求图片资源的时候加上一些没有一样的参数,让浏览器的缓存优化失效
这实际上让所有指定的资源都可以进行判断session中有没有user以此达到了拦截的效果
完整用户登录和权限检查
在前面的代码中我们只是测试当用户没有登录时,Filter是怎样拦截请求的,而没有测试当用户成功登录时,Filter是怎样放行的。下面将这种情况补充完整
- login.jsp页面
- 处理登录的LoginServlet程序
package com.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
final String username = req.getParameter("username");
final String password = req.getParameter("password");
//检查用户名和密码是否正确
if("admin".equals(username)&&"123456".equals(password)){
//登录成功
resp.getWriter().write("登录成功");
req.getSession().setAttribute("user",username);//将用户保持到session中
}else{
//登录失败
//请求转发回到登录页面
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}
}
}
- 过滤器程序(没有改变)
package com.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.http.HttpRequest;
public class AdminFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
//doFilter 方法,专门用于拦截请求。可以做权限检查
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpSession session = httpServletRequest.getSession();
if(session.getAttribute("user")==null){
/*请求转发到Login.jsp页面进行登录*/
servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);
return;
}else {
//让程序继续往下走访问用户目标资源(没有这行代码即使登录成功也不会继续访问目标资源)
filterChain.doFilter(servletRequest,servletResponse);
}
}
@Override
public void destroy() {
}
}
这将会达到一个效果,如果直接访问admin目录下面的资源,将会被拦截跳转进入longin.jsp页面。当我们登录成功后(验证登录成功的servlet程序不在拦截范围内),再次访问将将会被放行继续访问目标资源
Filter的生命周期
1.当我们项目启动时将会自动执行构造器和初始化方法,创建出构造器
2.当访问被限制的资源将会执行过滤方法
3.当项目关闭将会执行销毁方法
- 总结
FilterConfig类的介绍
- 程序代码
- 执行结果
FiilterChin多个过滤器执行的细节
FilterChain 过滤器链
- 过滤器链执行的原理
- Filter的配置
- 访问的资源文件
<%--
Created by IntelliJ IDEA.
User: SWT
Date: 2023/11/10
Time: 12:31
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入System--%>
<html>
<head>
<title>资源文件</title>
</head>
<body>
<%
System.out.println("这是resource.jsp文件");
%>
这是资源文件resource.jsp文件
</body>
</html>
我们仅仅是研究过滤器链的执行顺序,所有我们在前置代码(拦截请求)中都对他们进行了放行
验证1:所有过滤器和目标文件都是在同一个线程中
2.多个Filter执行时他们使用的是同一个Request对象(即属于同一个请求)
- 同一个请求即可以都可以获取到请求参数
- 同一个请求即可以访问相同的requet域(注意:往request域中存储数据和获取数据的代码需要考虑到过滤器链的执行顺序)