该例子有一个简单的过滤器,用于在一个文本中记录请求URL。
按照规范,过滤器累的名称必须以Filter结束。
@WebFilter(filterName="LoggingFilter",urlPatterns="/*",
initParams={
@WebInitParam(name="logFileName",value="log.txt"),
@WebInitParam(name="prefix",value="URI:")
}
)
//若注解不生效 可使用部署描述符
public class LoggingFilter implements Filter{
//声明两个变量 PrintWriter用来编写文本文件 prefix作为每个日志条目的前缀
private PrintWriter logger;
private String prefix;
@Override
public void destroy() {
// TODO Auto-generated method stub
//执行init会创建一个日志文件,如果应用程序目录下已经有同名文件存在,该文件将会被新文件覆盖
System.out.println("destroying filter");
if(logger != null){
logger.close();
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("LoggingFilter.doFilter");
/*doFilter方法通过将ServletRequest向下装换成HttpServletRequest,并调用其getRequestURI方法,记录下所有请求的日志。
* 然后将getRequestURI的结果填入PrintWriter的println方法中
*/
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
logger.println("时间:"+new Date()+" \n"+"prefix:"+prefix+"\nURI:"+httpServletRequest.getRequestURI());
/*
* 每个日志都有一个时间戳和前缀,以便识别。
* 之后doFilter方法接着刷新PrintWriter,并调用FilterChain.doFilter来调用资源。
*/
logger.flush();
filterChain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
/*
* init方法在传入的FilterConfig中调用getInitParameter方法,获取prefix和logFileName的初始值。
* prefix参数值赋给类级变量prefix,并与用logFileName创建一个PrintWriter
*/
prefix = filterConfig.getInitParameter("prefix");
String logFileName = filterConfig.getInitParameter("logFileName");
/*
* 为了在应用程序目录中创建一个日志文件,需要有一个它的绝对路径。
* 利用getRealPath获取,也就是将应用程序的logFileName初始参数合并
*/
String appPath = filterConfig.getServletContext().getRealPath("/");
System.out.println("logFileName:"+logFileName);
try {
logger = new PrintWriter(new File(appPath,logFileName));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
部署描述符、
<filter>
<filter-name>LoggingFilter</filter-name>
<filter-class>filter.LoggingFilter</filter-class>
<init-param>
<param-name>logFileName</param-name>
<param-value>log.txt</param-value>
</init-param>
<init-param>
<param-name>prefix</param-name>
<param-value>URI:</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LoggingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
效果,任意访问一个页面
log.txt (文件与WEB-INF同级):
并观察各阶段控制台的输出,建议戳断点调试,更直观的看出程序运行的步骤。