过滤器
什么是过滤器
过滤器(Filter):在Web服务器与Web资源之间加一层过滤机制,现实的是
javax.servlet.Filter
接口,可以处理request与response,用来拦截垃圾请求、过滤字符编码等。
过滤器的作用过程
- 用户提交表单信息,请求新的资源
- 请求进入到过滤器
- 过滤器进行过滤处理
- 处理完毕后将请求放行,请求到达Servlet
- Servlet处理完毕后,返回response
- response回到过滤器,处理后放行
- 响应用户新的资源
Filter链
在一个 Web 应用程序中可以注册多个 Filter 程序,每个 Filter 程序都可以对一个或一组 Servlet 程序进行拦截。如果有多个 Filter 程序都可以对某个 Servlet 程序的访问过程进行拦截,当针对该 Servlet 的访问请求到达时,Web 容器将把这多个 Filter 程序组合成一个 Filter 链(也叫过滤器链)。
Filter 链中的各个 Filter 的拦截顺序与它们在 web.xml 文件中的映射顺序一致,上一个 Filter.doFilter 方法中调用 FilterChain.doFilter 方法将激活下一个 Filter的doFilter 方法,最后一个 Filter.doFilter 方法中调用的 FilterChain.doFilter 方法将激活目标 Servlet的service 方法。
只要 Filter 链中任意一个 Filter 没有调用 FilterChain.doFilter 方法,则目标 Servlet 的 service 方法都不会被执行。
引自:Filter、FilterChain、FilterConfig 介绍
Filter接口
当需要用到过滤器时需要实现Filter接口,并重写里面的三个抽象方法:
public interface Filter {
default void init(FilterConfig filterConfig) throws ServletException {
}
void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException;
default void destroy() {
}
}
init
:
服务器启动时,进行初始化。服务器实例化Filter对象,读取web.xml中的相关配置信息,调用该方法,完成对象的初始化加载。filterConfig中保存了相关的配置信息和运行环境信息。
doFilter
:
当发出请求后,服务器先调用该方法,完成过滤处理。
destroy
:
web服务器关闭的时候自动调用该方法,过滤会销毁,释放资源
Filter映射
配置映射的方法与Servlet相同:
<filter>
<filter-name>CharacterFilter</filter-name>
<filter-class>Filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注:这是一个处理乱码的过滤器,可作用于所有请求与应答,则url-pattern中是所有内容。
编写过滤器
过滤器说明:利用过滤器实现乱码处理
public class CharacterFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterFilter初始化");
}
@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("过滤器执行前...");
//自己调自己,让程序继续运行,如果不写,程序到这里停止。
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("过滤器执行后...");
}
@Override
public void destroy() {
System.out.println("CharacterFilter销毁");
}
}
过滤器实例
实例说明:实现Vip用户登录,登录成功进入成功页面,登录失败进入失败页面,若用户直接访问成功页面则重定向到失败页面。
文件:登录页面、
LoginServlet.java
、
Success.jsp
、
VipFilter
(过滤器)、
LogoutServlet
(注销)、
ID.java
登录页面
<form method="post" action="/LoginServlet">
用户名:<input type="text" name="name">
<input type="submit" value="登录">
</form>
ID
将后面用到的session对象ID存在一个公共类中,方便修改。
public class ID {
public final static String SessionID = "ID";
}
LoginServlet
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
//判断登录的用户名是否为admin,即为VIP用户
if(name.equals("admin")){
//获取到Session的ID
request.getSession().setAttribute(ID.SessionID,request.getSession().getId());
response.sendRedirect("/Success/Success.jsp");
}else {
response.sendRedirect("Error.jsp");
}
}
过滤器
该过滤器作用在成功页面之前
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//若获取不到Session的ID,则证明不是由登录页面将来的,重定向至失败页面。
if(request.getSession().getAttribute(ID.SessionID) == null){
response.sendRedirect("Error.jsp");
}
filterChain.doFilter(request, response);
}
过滤器配置
在
web.xml
文件中给成功页面配置该过滤器。
<filter>
<filter-name>VipFilter</filter-name>
<filter-class>Filter.VipFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>VipFilter</filter-name>
<url-pattern>/Success/Success.jsp</url-pattern>
</filter-mapping>
Success.jsp
只有登录成功才能进入到该页面,当点击注销后跳转到
LogoutServlet
<h1>成功页面</h1>
<p><a href="/LogoutServlet" target="_blank" rel="external nofollow" >点我注销</a></p>
注销
当当用户点击注销后,相当于退出登录,则
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object ID = request.getSession().getAttribute(SessionID.ID.SessionID);
//若获取到的Session的ID不为空,则去除该Session对象,将页面重定向至登录页面
if (ID != null){
request.getSession().removeAttribute(SessionID.ID.SessionID);
response.sendRedirect("Login.jsp");
}
}
❤️ END ❤️