它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。servlet的过滤器,通过实现Filter
接口来实现。
过滤器的本质:过滤一些非法请求(常见的场景就是非法登录验证,以及一些需要登录后才能去访问的页面和资源),在浏览器和服务器响应中间添加一个拦截过滤请求的容器。
比如针对非法登录的用户的请求过滤:
当我们使用了Filter过滤器的时候,同样的场景,用户每一次发送请求的时候都要经过Filter过滤器,那么我们可以在过滤器里面编辑逻辑代码,进行判断当用户没有登录的时候,我们就让他跳转到提示错误的页面,在提示错误的页面里提示他只有登录了之后才可以访问系统主页。
首先,需要引入对应的包 javax.servlet
,和HttpServlet是同一个包下。
filter接口源码:
package javax.servlet;
import java.io.IOException;
public interface Filter {
default void init(FilterConfig filterConfig) throws ServletException {
}
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
default void destroy() {
}
}
创建一个类,实现filter接口,并且重写它的三个方法即可:
package com.robin.filter;
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 编写自己的业务逻辑代码即可
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
接着,去web.xml中配置过滤器:
<filter>
<filter-name>MyFilter filter-name>
<filter-class>com.robin.filter.MyFilterfilter-class>
filter>
<filter-mapping>
<filter-name>MyFilter filter-name>
<url-pattern>/servlet/*url-pattern>
filter-mapping>
package com.robin.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 ShowServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("我是中文字符");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.robin.filter;
import javax.servlet.*;
import java.io.IOException;
/**
* 自定义字符过滤器
*/
public class CharacterEncodingFilter implements Filter {
// 过滤器初始化
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
Filter.super.init(filterConfig);
}
//
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 设置过滤器的功能
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=utf-8");
System.out.println("CharacterEncodingFilter过滤器执行之前");
// 将自定义过滤器加入过滤器链中 filterChain 如果不加入链中,是无法执行过滤器的功能,以及拦截请求
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("CharacterEncodingFilter过滤器执行之后");
}
// 过滤器销毁
@Override
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
Filter.super.destroy();
}
}
<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">
<servlet>
<servlet-name>ShowServletservlet-name>
<servlet-class>com.robin.servlet.ShowServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>ShowServletservlet-name>
<url-pattern>/servlet/Showurl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>ShowServletservlet-name>
<url-pattern>/Showurl-pattern>
servlet-mapping>
<filter>
<filter-name>CharacterEncodingFilterfilter-name>
<filter-class>com.robin.filter.CharacterEncodingFilterfilter-class>
filter>
<filter-mapping>
<filter-name>CharacterEncodingFilterfilter-name>
<url-pattern>/servlet/*url-pattern>
filter-mapping>
web-app>
先访问走过滤器的请求http://localhost:8080/servlet/Show
,字符正确显示
访问不会走过滤器的请求http://localhost:8080/Show
,则输出乱码
其余的非法登录验证,以及敏感字符请求过滤等,本质都一样,大家可以自行测试
/
解释:会匹配到/login这样的路径型url,.js和.html等静态资源,不会匹配到*.jsp页面
/*
解释:会匹配所有url(只匹配当前文件夹下文件,不匹配子文件夹下文件),包括*.jsp页面
/**
解释:会匹配所有url(匹配当前文件夹下文件和子文件夹下文件):路径型的和后缀型的url(包括/login,.jsp,.js和*.html等)