Filter
用户访问请求需要经过Filter,并且可以有多个过滤器。
Filter 案例1
FirstFilter
package filter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
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;
/**
* FirstFilter--用来打印用户访问ip地址和访问的页面
* @author lzp
*
*/
public class FirstFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
// 转换为HttpServletRequest方便方法调用
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 获取ip地址
String ip = request.getRemoteAddr();
// 获取url
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);
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
web.xml filter设置
<filter>
<filter-name>FirstFilter</filter-name>
<filter-class>filter.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
Tomcat显示
filter 自启动
Filter 一定会随着Tomcat的启动而启动。
与servlet需要配置自启动才会随着Tomcat的启动而执行init()方法不同。
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("First Filter init()");
}
filter启动失败问题
filter启动失败,或本身编译错误,会导致filter不能使用,且整个web应用启动失败,用户无法访问web页面。
用Filter进行中文处理
servlet中获取中文参数,采用
request.setCharacterEncoding("UTF-8");
正确获取UTF-8编码中文,需要在每个servlet中添加该代码。
过滤器Filter2号
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;
public class EncodingFilter implements Filter{
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
web.xml设置
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
【注】:响应中文问题不需要加入filter
按照MVC设计模式,视图会交给jsp复制,jsp一般会加上
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%>
这一句包含了下面这句的意义
response.setContentType("text/html; charset=UTF-8");
http://blog.csdn.net/lizhongping00/article/details/69941796
使用Filter进行登陆验证处理
使用servlet中增加对session判断代码来做到登陆验证。故每个servlet都需要加上该代码。
AuthFilter
// 首先判断是否是访问login、login.html
login/login.html是登陆之前的界面,不需要session登陆验证,直接通过过滤即可。
如果不是登陆界面,如果从session中不能获取到值,重新登录。session会话为30分钟(Tomcat默认)
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;
public class AuthFilter implements Filter{
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 首先判断是否是访问login、login.html
// 这两个页面在还没登录之前就需要访问
String uri = request.getRequestURI();
if(uri.endsWith("login.html") || uri.endsWith("login")){
chain.doFilter(request, response);
return;
}
// 从session中获取userName,如果没有就表示未登陆过。
String userName = (String) request.getSession().getAttribute("userName");
if(null == userName){
response.sendRedirect("login.html");
return ;
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
web.xml 设置
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>filter.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在login.jsp页面中js,css和图片文件
用上面的验证,在登陆之前所有资源是不能访问的。
如果在login.jsp页面中js,css和图片文件,想要访问这些资源,需要对过滤器进行修改。
思路即是在预先判断是否是js或css资源,如果是直接通过,不需要进行验证登录。
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 获取参数uri串
String uri = request.getRequestURI();
// 如果访问的资源是以css或者js结尾的,那么就不需要判断登录
if (uri.endsWith(".css") || uri.endsWith(".js")) {
chain.doFilter(request, response);
return;
}
// 首先判断是否是访问login、login.html
// 这两个页面在还没登录之前就需要访问
if (uri.endsWith("login.html") || uri.endsWith("login")) {
chain.doFilter(request, response);
return;
}
// 从session中获取userName,如果没有就表示未登陆过。
String userName = (String) request.getSession().getAttribute("userName");
if (null == userName) {
response.sendRedirect("login.html");
return;
}
chain.doFilter(request, response);
}
【注】
chain.doFilter(request, response);
return; // 用于不允许后面的功能了
表示该过滤器放行,继续运行下一个过滤器,或者访问到资源了。