Java EE 8 Design Patterns and Best Practices
上QQ阅读APP看书,第一时间看更新

Implementing LogAccessFilter

Here, we have the implementation of LogAccessFilter:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

@WebFilter(filterName = "LogAccess", urlPatterns = "/*")
public class LogAccessFilter implements javax.servlet.Filter {

private static Logger logger = LogManager.getLogger(LogAccess.class);

public void destroy() {
}

public void doFilter(javax.servlet.ServletRequest req,
javax.servlet.ServletResponse resp, javax.servlet.FilterChain
chain) throws javax.servlet.ServletException, IOException {

//Gets the initial date of request.
Date dateInitRequest = new Date();

//Get IP of Client that sent a resquest.
String ip = ((HttpServletRequest)req).getRemoteAddr();

//Following to next filter. If none next filter exist, follows
//for main logic.
chain.doFilter(req, resp);

//Gets the end date of request.
Date dateEndRequest = new Date();

//Logging the informations of IP and access time.
logger.info("IP: "+ip +" Access time : "
+ Long.toString(dateEndRequest.getTime()
- dateInitRequest.getTime())
+ " ms");

}

public void init(javax.servlet.FilterConfig config) throws
javax.servlet.ServletException {

}

}

As we can see in the code, to create one servlet filter, we need to create a class that extends javax.servlet.Filter and puts the @WebFilter annotation with filterName and urlPatterns parameters, which define the filter name and the URLs to filter, before the definition of class. The following is a snippet of code that demonstrates how to do that:

@WebFilter(filterName = "LogAccess", urlPatterns = "/*")
public class LogAccessFilter implements javax.servlet.Filter{
...
}

Note that the servlet filter uses the chain of responsibility pattern to walk throughout the filters (objects that are servlet filter). The following is a snippet of code that uses a chain of responsibility pattern:

chain.doFilter(req, resp);

In the preceding line of code, we established the filter name as LogAccess through the filterName parameter. This will filter all requests, because the urlPatterns parameter has the "/*" value. If we filter according to servlet name, we need to use the following annotation:

//Servlet1 and Servlet2 are the servlets to filter.
@WebFilter
(filterName = "LogAccess", servletNames = {"servlet1","servlet2"})

The doFilter method is responsible for pre-processing and post-processing and establishes when to follow the request to the next filter or servlet (main logic). To follow the request to the next filter or servlet, the following code needs be executed:

//Following to next filter or servlet.
chain.doFilter(req, resp);

When the preceding code is executed, the current filter executes only the next line when the other filters and servlets finish their processing.