过滤器Filter
本文章基于B站UP主:楠哥教你学Java 的课程《Java Web从入门到实战【完整版】》进行整理补充,本文章仅用于个人学习交流使用。
1.基本概念
Filter 就是对传入的数据做一个检查,修改之后,并向后继续传输
功能:
1、⽤来拦截传⼊的请求和传出的响应。
2、修改或以某种⽅式处理正在客户端和服务端之间交换的数据流。
2.创建使用
使⽤:
与使⽤ Servlet 类似, Filter 是 Java WEB 提供的⼀个接⼝,开发者只需要⾃定义⼀个类并且实现该接⼝。注意,引入的是 import javax.servlet.Filter 里面的接口。同时需要在 xml 文件里面进行 “映射”,或使用注解 @WebFilter 的方式进行映射。
引入:当创建了多个 servlet 文件,为了处理乱码,每个文件都需要添加 ,会使代码冗杂,使用过滤器统一实现处理乱码等问题。
注意: doFilter ⽅法中处理完业务逻辑之后,必须添加
filterChain.doFilter(servletRequest,servletResponse);
否则请求/响应⽆法向后传递,⼀直停留在过滤器中 。
过滤器:CharacterFilter.java
package com.lut.filter;
import javax.servlet.*;
import java.io.IOException;
public class CharacterFilter implements Filter {
//Filter里面的接口(一共有三个)不一定需要全部实现,只有 doFilter 不实现会报错
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("UTF-8");
//必须添加,使继续传递下去
filterChain.doFilter(servletRequest,servletResponse);
}
}
XML文件: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">
<filter>
<filter-name>character</filter-name>
<filter-class>com.lut.filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>character</filter-name>
<url-pattern>/login</url-pattern>
<url-pattern>/test</url-pattern>
</filter-mapping>
</web-app>
Servlet文件:TestServlet.java
@WebServlet("/test")
public class TestServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//req.setCharacterEncoding("UTF-8");
String value=req.getParameter("value");
System.out.println(value);
}
}
3.生命周期
当 Tomcat 启动时,通过反射机制调⽤ Filter 的⽆参构造函数创建实例化对象,同时调⽤ init ⽅法实现初始化, doFilter ⽅法调⽤多次,当 Tomcat 服务关闭的时候,调⽤ destory 来销毁 Filter 对象。
⽆参构造函数:只调⽤⼀次,当 Tomcat 启动时调⽤(Filter ⼀定要进⾏配置)
init ⽅法:只调⽤⼀次,当 Filter 的实例化对象创建完成之后调⽤
doFilter:调⽤多次,访问 Filter 的业务逻辑都写在 Filter 中
destory:只调⽤⼀次, Tomcat 关闭时调⽤。
同时配置多个 Filter, Filter 的调⽤顺序是由 web.xml 中的配置顺序来决定的,写在上⾯的配置先调⽤,因为 web.xml 是从上到下顺序读取的 。
可以使用注解的方式 @WebFilter("/login") 简化xml里面的配置,但使用注解,并且有多个Filter时,无法决定执行的先后顺序,如果有先后顺序的需求,建议使用 xml 配置,不过注解方式一般够用。
4.使用场景
1.统一处理中文乱码
@WebFilter("/login")
public class CharacterFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("UTF-8");
//必须添加,使继续传递下去
filterChain.doFilter(servletRequest,servletResponse);
}
}
2.屏蔽敏感词
信息提交页面:test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<body>
<form action="test" method="post">
<input type="text" name="name"/>
<input type="submit" value="提交"/>
</form>
</body>
</body>
</html>
过滤器:WordFilter.java
package com.lut.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/test")
public class WordFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("UTF-8");
//将 “敏感词” 替换成 “***”
String name=servletRequest.getParameter("name");
System.out.println(name);
name=name.replaceAll("敏感词","***");
System.out.println(name);
servletRequest.setAttribute("name",name);//重点:将处理好的信息返回Service
filterChain.doFilter(servletRequest,servletResponse);
}
}
将处理好的信息返回Service
Service:TestServlet.java
package com.lut.servlet;
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;
@WebServlet("/test")
public class TestServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name=(String) req.getAttribute("name");//重点:获取处理后的信息
System.out.println("Servlet"+name);
}
}
3.控制资源的访问权限
[例如只有登录用户才能下载网站的资源]
登录界面:login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="login" method="post">
<input type="text" name="name"><br>
<input type="password" name="password"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
过滤器:DownloadFilter.java
package com.lut.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter("/download.jsp")
// .jsp文件是直接访问,Servlet是通过映射间接访问
public class DownloadFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//有没有登录-->检测scssion里面有没有存用户信息
HttpServletRequest request=(HttpServletRequest) servletRequest;//向下转型
HttpServletResponse response=(HttpServletResponse) servletResponse;
HttpSession session=request.getSession();
String name=(String) session.getAttribute("name");
if (name==null){
//不是登录
response.sendRedirect("login.jsp");
}else {
//是登陆,继续操作
filterChain.doFilter(servletRequest,servletResponse);
}
}
}
登录Service:LoginServlet.java
package com.lut.servlet;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name=req.getParameter("name");
String password=req.getParameter("password");
if (name.equals("admin")&&password.equals("123456")){
HttpSession session =req.getSession();
session.setAttribute("name",name);
resp.sendRedirect("/download.jsp");
}
}
}
下载界面:download.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="">资源1</a>
<a href="">资源2</a>
<a href="">资源3</a>
</body>
</html>
界面展示:
直接在浏览器地址输入 直接访问下载界面时,会强制跳转到 登录界面。
![](https://i-blog.csdnimg.cn/blog_migrate/5412f2076f04b1d249a146cba2afcff4.png)
成功登录之后,才可以进行下载
![](https://i-blog.csdnimg.cn/blog_migrate/84cb855b8bab1422cedc47c46fc82513.png)