Logging, security, compression, network analysis, and even HTML decoration all make use of the request-response packets going from and to your application. When writing some component (maybe even with the intention of being reusable) to perform the task(s) at hand, you would probably end up with some "if-then-else" decision logic. This would control the packet stream's flow of execution. However, you'll probably end up with duplicate code in multiple (if not all) conditional branches of your control unit; all performing the same task. Furthermore, hard coding the flow of control will probably result in an application specific solution.
The dynamic behaviour in this context would be the individual/unique operations performed by each process unit for logging, security etc. The static behaviour in this context would be the packet stream itself. To write a reusable component we would need to capture the dynamic content and encapsulate it. Rather than having a component with decision logic to address every conceivable configuration or setup, we could instead use several smaller components that are declared declaratively. These components would then be declared in a configuration file, each one contributing to the application's specific need.
The small individual components would add small features such as logging or security to the system, thus encapsulating the dynamic behaviour. For reusability, it is important to decouple these components from any application specific code. The best place to put these components would either be before or after the packet stream enters the application. This leads to the definition of the terms pre-processing and post-processing of an incoming HTTP request. The individual, reusable components are called filters.
The Servlet Specification, version 2.3, includes a standard mechanism for building filter chains and unobtrusively adding or removing filters from those chains. To build up this chain of filters, some sort of filter-to-filter communication would be needed. How would a filter know which filter to send to next ? The solution is to use a filter manager. The filter manager will read an application's filter configuration file and use it to manage the filtering process. Each filter would then need to adhere to some common filter interface so that the manager would know how to invoke each one. This is called the Standard Filter Strategy and is only one of many strategy's for applying the Intercepting Filter pattern.
The code below gives you an idea of how a filter looks like. The doFilter method will cause the next filter in the filter chain to be executed. A request would enter the first filter in the filter chain and move through consecutive filters until it enters the application itself. Upon return, the response would move through the same filters, but this time in the opposite order.
/**
* This code is from an example within "core J2EE PATTERNS, Best Practices and Design
* Strategies".
**/
public class BaseEncodingFilter implements javax.servlet.Filter {
private javax.servlet.FilterConfig filterConfig;
public void doFilter(javax.servlet.ServletRequest servletRequest,
javax.servlet.ServletResponse servletResponse,
javax.servlet.FilterChain filterChain)
throws java.io.IOException, javax.servlet.ServletException {
filterChain.doFilter(servletRequest, servletResponse);
}
protected javax.servlet.FilterConfig getFilterConfig() {
return filterConfig;
}
public void destroy() { }
public void init(javax.servlet.FilterConfig filterConfig)
throws javax.servlet.ServletException
this.filterConfig = filterConfig;
}
}
In the subsequent parts, I will elaborate more on other Intercepting Filter strategies
and the filter process overall to eventually write a complete Filter component.
SDTimes, Oredev2011, Rubyfuza2012, AgileIndia2012
-
Over the next few months or so, I will be quite active in the conference
space. Here’s what’s coming up soon … SD Times’ Leaders of Agile Webinar:
This is...
4 months ago
0 comments:
Post a Comment