Filter(过滤器)
Filter
功能:
1.用来拦截传入和传出的响应。
2.修改或以某种方式处理正在客户端和服务端之间交换的数据流。
使用方法:
与使用Servlet相似,Filter是JavaWeb提供的一个接口,开发者只要自定义一个类并且实现该接口即可。
注意事项:
1.接口实现时一定要引用 Filter(Javax.servlet)
2.doFilter()方法处理完业务逻辑之后,必须使用 filterChain对象调用 doFilter()方法,将请求/响应向后边传递,否则该请求/响应会一直滞留在过滤器中。
package com.wildfire.servlet.Filter;
import javax.servlet.*;
import java.io.IOException;
/*一定要引用 Filter(javax.servlet)*/
public class CharacterFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("UTF-8");
/*doFilter方法中处理完业务逻辑之后,必须添加filterChain.doFilter(servletRequest,servletResponse);
否则请求/响应无法向后传递,会一直停留在过滤器中*/
servletResponse.setCharacterEncoding("UTF-8");
filterChain.doFilter(servletRequest,servletResponse);
}
}
在web.xml中配置文件
<filter>
<filter-name>CharacterFilter</filter-name>
<filter-class>com.wildfire.servlet.Filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterFilter</filter-name>
<url-pattern>/Filter1Servlet</url-pattern>
<url-pattern>/Filter2Servlet</url-pattern>
</filter-mapping>
Filter的生命周期
当Tomcat启动是,通过反射机制调用Filter的无参构造函数实例化对象,同时调用init方法来实现初始化,doFilter方法会执行多次,当Tomcat服务关闭时,调用destory来销毁Filter对象。
⽆参构造函数:只调⽤⼀次,当 Tomcat 启动时调⽤(Filter ⼀定要进⾏配置,否则不会加载)。
init ()⽅法:只调⽤⼀次,Tomcat启动后,当 Filter 的实例化对象创建完成之后调⽤。
doFilter():调⽤多次,访问 Filter 的业务逻辑都写在 Filter 中。
destory():只调⽤⼀次,Tomcat 关闭时调⽤。
同时配置多个Filter,Filter的调用顺序是由web.xml中的配置顺序来决定的,配置写在前面的先调用,配置写在后面的后调用,因为web.xml是从上到下顺序读取的。
<filter>
<filter-name>CharacterFilter</filter-name>
<filter-class>com.wildfire.servlet.Filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterFilter</filter-name>
<url-pattern>/Filter1Servlet</url-pattern>
<url-pattern>/Filter2Servlet</url-pattern>
</filter-mapping>
<filter>
<filter-name>CharacterFilter2</filter-name>
<filter-class>com.wildfire.servlet.Filter.CharacterFilter2</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterFilter2</filter-name>
<url-pattern>/Filter1Servlet</url-pattern>
<url-pattern>/Filter2Servlet</url-pattern>
</filter-mapping>
也可以通过注解的方式来简化过滤器的配置,但是使用注解的方法无法设定过滤器的执行顺序。
@WebServlet("/CharacterFilter2")
public class CharacterFilter2 implements Filter {
}
以上代码等同于在web.xml中配置,在web.xml中配置文件的代码如下:
<filter>
<filter-name>CharacterFilter2</filter-name>
<filter-class>com.wildfire.servlet.Filter.CharacterFilter2</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterFilter2</filter-name>
<url-pattern>/Filter1Servlet</url-pattern>
<url-pattern>/Filter2Servlet</url-pattern>
</filter-mapping>
实际开发中用到Filter的场景:
1.统一处理中文乱码。
2.屏蔽敏感词
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Filter3</title>
</head>
<body>
<form action="/WordServlet" method="get">
文字:<input type="text" name="text">
<input type="submit" value="提交">
</form>
</body>
</html>
package com.wildfire.servlet.Filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/WordServlet")
public class WordFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("UTF-8");
String text=servletRequest.getParameter("text");
/*这是个简单的例子,并没有词库,就单纯的将输入的 敏感词 三个字,替换为*** */
text=text.replaceAll("敏感词","***");
/*上面text我们取出了,并对其进行了修改,但是Parameter中的text并没有修改,如果继续往下传递,传递的依然是未进行修改的text
同时系统没有提供setParameter()方法,可以用setAttribute() 将修改后的值传递下去*/
servletRequest.setAttribute("text",text);
filterChain.doFilter(servletRequest,servletResponse);
}
}
package com.wildfire.servlet.Filter;
import com.wildfire.servlet.HttpServlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/WordServlet")
public class WordServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/* 使用setAttribute()方法存的,就要用对应的方法取出来*/
String text=(String)req.getAttribute("text");
String text1=req.getParameter("text");
System.out.println("屏蔽前的文字:"+text1);
System.out.println("屏蔽后的文字:"+text);
}
}
3.控制资源访问权限
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>下载页面</title>
</head>
<body>
<h1>下载</h1>
<a href="">资源一</a>
<a href="">资源二</a>
<a href="">资源三</a>
</body>
</html>
package com.wildfire.servlet.Filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter("/Filter4_downloading.jsp")
public class DowdingFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletResponse response=(HttpServletResponse)servletResponse;
HttpSession session =request.getSession();
String name=(String)session.getAttribute("name");
if(name==null){
//不是登录状态,不允许下载,跳转到登录界面
response.sendRedirect("Filter5_login.jsp");
}else{
filterChain.doFilter(servletRequest, servletResponse);
}
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录</h1>
<form action="/DownloadingServlet" method="post">
账号:<input type="text" name="name"><br/>
密码:<input type="password" name="password"><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
package com.wildfire.servlet.Filter;
import com.wildfire.servlet.HttpServlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/DownloadingServlet")
public class DownLoadingServlet 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("123")){
HttpSession session=req.getSession();
session.setAttribute("name",name);
resp.sendRedirect("Filter4_downloading.jsp");
}
}
}
package com.wildfire.servlet.Filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter("/Filter4_downloading.jsp")
public class DowdingFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletResponse response=(HttpServletResponse)servletResponse;
HttpSession session =request.getSession();
String name=(String)session.getAttribute("name");
if(name==null){
//不是登录状态,不允许下载,跳转到登录界面
response.sendRedirect("Filter5_login.jsp");
}else{
filterChain.doFilter(servletRequest, servletResponse);
}
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>下载页面</title>
</head>
<body>
<h1>下载</h1>
<a href="">资源一</a>
<a href="">资源二</a>
<a href="">资源三</a>
</body>
</html>