过滤器:不仅会实现对web资源的拦截,还会对请求做预处理操作,对要返回的响应做后处理操作
过滤器常见概念:
工作流程:
生命周期:
开发步骤:
过滤器链:
注册顺序决定的是预处理时候的调用顺序,而后处理调用顺序是其逆序
过滤器对请求的处理流程:
案例:留言板过滤器 FilterDemo
字符集编码过滤器:
CharacterEncodingFilter.java:
package filter;
/**
* 字符集编码过滤器
* @author lcs
*/
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
//字符集编码过滤器
public class CharacterEncodingFilter implements Filter {
//获取参数对象
private FilterConfig config;
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//对请求进行编码集处理,将请求的编码集设置成web.xml配置的编码
request.setCharacterEncoding(config.getInitParameter("charset"));// 根据过滤器配置字符集,设置请求字符集编码
System.out.println("characterEncodingFilter 请求预处理");//测试过滤器(链)工作流程使用
//告诉过滤器链可以进行下一步的拦截处理
chain.doFilter(request, response);
// System.out.println("characterEncodingFilter 响应后处理");//测试过滤器(链)工作流程使用
}
@Override
//初始化操作
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
// getter setter
public FilterConfig getConfig() {
return config;
}
public void setConfig(FilterConfig config) {
this.config = config;
}
}
在web.xml文件里进行配置
<!-- 字符集编码过滤器配置 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>filter.CharacterEncodingFilter</filter-class>
<!-- 初始化参数 -->
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
用户登录安全控制过滤器:
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 用户登录安全控制过滤器
*
* @author lcs
*
*/
public class SessionFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 涉及到HTTP请求处理,转型处理
HttpServletRequest hrequest = (HttpServletRequest) request;
// 涉及到HTTP请求处理,转型处理
HttpServletResponse hresponse = (HttpServletResponse) response;
// 判断用户是否完成了登录操作,session中是否存储用户名
String loginUser = (String) hrequest.getSession().getAttribute("loginUser");
if (loginUser == null) {
// 未登录,系统强制重定向至登录页面
hresponse.sendRedirect(hrequest.getContextPath() + "/index.jsp?flag=1");
return;
} else {
chain.doFilter(hrequest, hresponse);
return;
}
}
@Override
public void init(FilterConfig config) throws ServletException {
}
}
在web.xml进行配置:
<!-- 用户登录安全控制过滤器配置 -->
<filter>
<filter-name>sessionFilter</filter-name>
<filter-class>filter.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<url-pattern>/message.jsp</url-pattern>
</filter-mapping>
Java过滤器配置:
dispatcher:
REQUEST:
只要发起的操作是一次HTTP请求,比如请求某个URL、发起了一个GET请求、表单提交方式为POST的POST请求、表单提交方式为GET的GET请求。一次重定向则前后相当于发起了两次请求,这些情况下有几次请求就会走几次指定过滤器。
INCLUDE:
只要是通过<jsp:include page="xxx.jsp" />
,嵌入进来的页面,每嵌入的一个页面,都会走一次指定的过滤器。
FORWARD:
只有当当前页面是通过请求转发转发过来的情形时,才会走指定的过滤器。
ERROR:
假如web.xml里面配置了<error-page></error-page>:
<error-page>
<error-code>400</error-code>
<location>/filter/error.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/filter/error.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/filter/error.jsp</location>
</error-page>
意思是HTTP请求响应的状态码只要是400、404、500三种状态码之一,容器就会将请求转发到error.jsp下,这就触发了一次error,走进了配置的DispatchFilter。需要注意的是注意一点的是,虽然把请求转发到error.jsp是一次forward的过程,但是配置成<dispatcher>FORWARD</dispatcher>
并不会走DispatchFilter这个过滤器。
这四种dispatcher方式可以单独使用,也可以组合使用,配置多个<dispatcher></dispatcher>
即可。