概念
Filter就像一个一个哨卡,用户的请求需要经过Filter
可以有多个过滤器
FirstFliter
用IDEA创建一个Filter,会自动初始化
@WebFilter(filterName = "FirstFilter")
public class FirstFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
我们做一个简单的Filter,来打印用户访问ip地址和访问的页面
-
doFilter()方法中的req参数的类型是ServletRequest,需要转换为HttpServletRequest类型方便调用某些方法
HttpServletRequest request = (HttpServletRequest) req;
-
获取IP地址、页面地址、时间
String ip = request.getRemoteAddr(); String url = request.getRequestURL().toString(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d = new Date(); String date = sdf.format(d);
-
打印
System.out.printf("%s %s 访问了 %s%n", date, ip, url);
-
过滤器放行,表示继续运行下一个过滤器,或者最终访问的某个servlet,jsp,html等等
chain.doFilter(request, response);
-
配置web.xml
<filter> <filter-name>FirstFilter</filter-name> <filter-class>FirstFilter</filter-class> </filter> <filter-mapping> <filter-name>FirstFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<url-pattern>/*</url-pattern>
表示所有访问都被过滤<url-pattern>*.jsp</url-pattern>
表示只过滤jsp -
init方法
Filter一定会随着tomcat的启动自启动
-
启动失败事项
Filter是web应用非常重要的一个环节,如果Filter启动失败,或者本身有编译错误,不仅这个Filter不能使用,整个web应用会启动失败,导致用户无法访问页面
在启动tomcat过程中,也会看到这样的字样:
严重: Context [] startup failed due to previous errors
应用
中文处理
我们知道为了获取中文需要设置 request.setCharacterEncoding("UTF-8");
如果有多个Servlet,每次都要设置就很麻烦
所以可以用Filter来批量处理
创建一个EncodingFilter
@WebFilter(filterName = "EncodingFilter")
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest)req;
req.setCharacterEncoding("UTF-8");
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
然后配置xml,就可以了
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
验证登陆
创建一个AuthFilter类
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
String uri = request.getRequestURI();
if(uri.endsWith("login.html")||uri.endsWith("login")){
chain.doFilter(req,resp);
return; // 要记得return
}
String userName = (String)request.getSession().getAttribute("userName");
if(null == userName){
response.sendRedirect("login.html");
return;
}
chain.doFilter(req,resp); // 千万别把这个漏了
}
- 如果访问的是login,本来就是在还没有登陆之前就需要访问的,放行
- 否则进行验证
- 如果未登录,跳转到login.html
配置xml,就可以了
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>