- 什么是过滤器
- 写过滤器的步骤
- 配置初始化参数
- 过滤器的优先级
- 过滤器的优点
- 过滤器执行过程图解
- 过滤敏感词的示例代码
- 使用 Servlet 来过滤敏感词
- 使用过滤器来过滤敏感词
- 通过配置初始化参数来设置敏感词
- 关于 web.xml 的配置
Servlet 规范当中定义的一种特殊的类,用于对 Servlet 容器的调用过程进行拦截。
写过滤器的步骤step1 写一个 java 类,实现一个 Filter 接口。 step2 在 doFilter 方法里,实现过滤的逻辑。 step3 配置(web.xml)。
配置初始化参数step1 web.xml 中,使用 元素来配置初始化参数 step2 在 Filter 类中,使用
FilterConfig.getInitParameter(String paraName);
获得初始化参数。
当有多个过滤器都满足过滤的条件时,依据 的先后顺序依次执行。
a. 可以将多个 web 组件相同的逻辑写在一个过滤器当中,方便代码的维护 b. 可实现代码的“可插拔性"。 给一个软件增加戒者减少某个功能不会影响已经存在的功能。
过滤器执行过程图解- 浏览器发送请求给服务器
- 服务器的 Servlet 引擎创建 Request 对象&&Response 对象
- Servlet 引擎先调用过滤器的 doFilter 方法,该方法有两个参数 request 和 response, (在过滤器中可以访问到 Request 对象&&Response 对象)
- 过滤器对拦截的内容迚行处理
- 之后调用 SomeServlet 的 service 方法
- service 方法执行
- service 方法执行结束后,将结果返回到过滤器
- 过滤器将 service 方法返回的结果再次进行过滤
- 最后,Servlet 引擎将结果返回给浏览器
实现敏感词过滤功能,如果没有使用过滤器,我们使用 Servlet 来实现。
JSP 页面代码:
Title
input your comment:
Servlet 代码:
package priv.lwx.servlet.filter.web;
import org.junit.jupiter.api.Test;
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;
import java.io.PrintWriter;
/**
* description
*
* @author liaowenxiong
* @date 2022/2/23 22:40
*/
@WebServlet("/process")
public class ProcessServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
String comment = req.getParameter("comment");
if (comment.indexOf("dog") >= 0) {
out.println("含有违禁关键字");
} else {
out.println("你的评论是:" + comment);
}
out.close();
}
@Test
public void test() {
System.out.println("dog".indexOf("dog"));
}
}
使用过滤器来过滤敏感词
Filter 的代码如下:
package priv.lwx.servlet.filter;
/**
* 评论敏感词过滤器
*
* @author liaowenxiong
* @date 2022/2/23 23:14
*/
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.io.PrintWriter;
@WebFilter("/process")
public class CommentFilter implements Filter {
/**
* Servlet 容器在创建好 Filter 实例之后,会立即创建
* FilterConfig 实例并调用 init()方法,将 FilterConfig
* 实例作为参数传递过去。通过该实例,可以访问 Filter 的初始化参数。
* String FilterConfig.getInitParameter(String paraName);
* init()方法只会执行一次。
*
* @param config
* @throws ServletException
*/
public void init(FilterConfig config) throws ServletException {
System.out.println("init...");
}
/**
* 在容器删除Filter实例之前,调用该方法。
* 只会执行一次。
*/
public void destroy() {
System.out.println("destroy...");
}
/**
* 当请求到达容器,容器会调用 doFilter 方法。
* 容器会将事先创建好的 request,response 对象作为
* 参数传递过去。
* FilterChain:过滤器链。
* 如果调用了 FilterChain.doFilter 方法,表示调用
* 后续的过滤器。如果没有过滤器了,则调用对应的 web 组件。
*
* @param request
* @param response
* @param chain
* @throws ServletException
* @throws IOException
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
request.setCharacterEncoding("utf8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String comment = request.getParameter("comment");
if (comment.indexOf("dog") >= 0) {
out.println("评论中含有敏感词!");
} else {
// 调用后续的过滤器,如果没有了,则调用Web组件
chain.doFilter(request, response);
}
}
}
注意点:过滤器的请求路径(即url-pattern)必须与web组件(Servlet)的url-pattern相同。
Servlet 的代码如下:
package priv.lwx.servlet.filter.web;
import org.junit.jupiter.api.Test;
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;
import java.io.PrintWriter;
/**
* description
*
* @author liaowenxiong
* @date 2022/2/23 22:40
*/
@WebServlet("/process")
public class ProcessServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
String comment = req.getParameter("comment");
out.println("你的评论是:" + comment);
out.close();
}
@Test
public void test() {
System.out.println("dog".indexOf("dog"));
}
}
通过配置初始化参数来设置敏感词
Filter 的示例代码:
package priv.lwx.servlet.filter;
/**
* 评论敏感词过滤器
*
* @author liaowenxiong
* @date 2022/2/23 23:14
*/
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
@WebFilter(value = "/process", initParams = {@WebInitParam(name = "illegalStr0",
value = "dog"), @WebInitParam(name = "illegalStr1", value = "pig")})
public class CommentFilter implements Filter {
private FilterConfig config;
/**
* Servlet 容器在创建好 Filter 实例之后,会立即创建
* FilterConfig 实例并调用 init()方法,将 FilterConfig
* 实例作为参数传递过去。通过该实例,可以访问 Filter 的初始化参数。
* String FilterConfig.getInitParameter(String paraName);
* init()方法只会执行一次。
*
* @param config
* @throws ServletException
*/
public void init(FilterConfig config) throws ServletException {
System.out.println("init...");
config = config;
}
/**
* 在容器删除Filter实例之前,调用该方法。
* 只会执行一次。
*/
public void destroy() {
System.out.println("destroy...");
}
/**
* 当请求到达容器,容器会调用 doFilter 方法。
* 容器会将事先创建好的 request,response 对象作为
* 参数传递过去。
* FilterChain:过滤器链。
* 如果调用了 FilterChain.doFilter 方法,表示调用
* 后续的过滤器。如果没有过滤器了,则调用对应的 web 组件。
*
* @param request
* @param response
* @param chain
* @throws ServletException
* @throws IOException
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
request.setCharacterEncoding("utf8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String comment = request.getParameter("comment");
Enumeration initParameterNames = config.getInitParameterNames();
// 是否含有敏感词,默认无
boolean isIllegal = false;
while (initParameterNames.hasMoreElements()) {
String initParameterName = initParameterNames.nextElement();
String initParameter = config.getInitParameter(initParameterName);
if (comment.indexOf(initParameter) >= 0) {
// 含有敏感词
isIllegal = true;
out.println("评论中含有敏感词:" + initParameter);
break;
}
}
if (!isIllegal) {
// 没有敏感词,则调用后续的过滤器,如果没有过滤器,则调用Web组件
chain.doFilter(request, response);
}
}
}
注意点:注解 WebFilter 的 属性 initParams,其值是一个注解数组,即数组元素的类型就是 @WebInitParam,或者说数组元素是 @WebInitParam 的实例对象。
赋值示例代码如下:
initParams = {@WebInitParam(name = "illegalStr0",value = "dog"), @WebInitParam(name = "illegalStr1", value = "pig")}
解读: 注解 WebInitParam 用来封装参数,方法 initParams 用来从 WebInitParam 对象获取参数,再将参数封装到 Request 对象中。
Servlet 的示例代码:
package priv.lwx.servlet.filter.web;
import org.junit.jupiter.api.Test;
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;
import java.io.PrintWriter;
/**
* description
*
* @author liaowenxiong
* @date 2022/2/23 22:40
*/
@WebServlet("/process")
public class ProcessServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
String comment = req.getParameter("comment");
out.println("你的评论是:" + comment);
out.close();
}
@Test
public void test() {
System.out.println("dog".indexOf("dog"));
}
}
关于 web.xml 的配置
上面的示例并没有在 web.xml 文件中对 Servlet、Filter 进行配置,采用的都是注解配置。如果要在 web.xml 配置 Servlet、Filter 请参考下面的配置内容:
filter1
priv.lwx.servlet.filter.CommentFilter
illegalStr0
dog
illegalStr1
pig
filter1
/process
process
priv.lwx.servlet.filter.web.ProcessServlet
process
/process