saoj
Joined: 22/12/2007 07:20:02
Messages: 22
Offline
|
Filters are the building blocks of Mentawai through which all the main feature of the framework are implemented. A filter wraps or intercepts an action so that it can change everything about the action before it is actually executed. A filter always gets executed before the action, but as we will see in a moment it can also modify the action after it has been executed. For a single action you will usually have a stack of filters (InvocationChain) being executed before the action. You can define global filters that will be applied on all actions or you can define action specific filters that will be applied only on that action. Filters are powerful, simple and flexible. They favor the Separation of Concerns pattern, allowing your action to do one thing and do it right! For example, there is no need for your action code to get convoluted with validation code, file upload code, connection pooling code, etc. This can and should be abstracted outside your action through filters.
Mentawai comes with many ready-to-use filters, but you should understand how they work and how to build your own filters. Building filters are very simple and you should have this weapon ready to kill unnecessary complexity in your code. Let's start coding some filters.
A filter that gets a Map from the application and places it in the action input:
This was a somewhat unrealistic example as your action can just access the application context and get the cache map itself. However it is useful to understand the basic functionality of filters.
Through the InvocationChain object passed as a parameter to the filter you can get the action before it has been executed. Having the action, you can now access its Input, Output and contexts such as the Application context. After the filter is done, it should call chain.invoke() unless it wants to halt the action execution. The invoke method will call the next filter in the filter stack or the action if there are no more filters in the stack. It returns the action result (String) which will be in turn returned by the filter.
There will be cases when you do want to block the access to the action, for example when you are using an authentication filter. An authentication filter may look like the filter below:
In the filter above we are checking if the use is logged in the system, before allowing the action to be executed. If we find an object in the session for the key "user" we assume that the user is logged and call invoke(). If the user is not logged than we return the result LOGIN which may redirect the browser to a login page.
A filter can modify the action before and also after the action has been executed. Check the example below which calculates the total time the action has taken to execute:
Note how we are modifying the action output before and after the action has been executed. Another possibility is to use the AfterConsequenceFilter, which inherits from the Filter interface, to perform some task after the consequence has been executed. Let's change our TimerFilter to compute the time it takes for the consequence to execute:
Why didn't we place the total consequence time in the action output as well, so that we could show it in the JSP page? That's because after the consequence is executed the JSP page is history. The page was already processed so placing new things in the action output will not do us any good. That's why we chose to use the System.out to display the total consequence time.
The AfterConsequenceFilter is useful for example for the HibernateFilter so that the hibernate session is closed only after the view layer has been processed and any lazy loading has been done.
Filters can do many other things as we will see in later chapters. It can do input validation, handle exceptions, open transactions, inversion of control, etc. Filters prepare everything for the action, so that when it is time for the action to get executed, everything is ready, organized and beautiful.
Below is an example of an ApplicationManager that is using the CacheFilter and the TimerFilter described above. You can also download by clicking here an application that makes use of both filters. Run this application and you will be surprised by the Mentawai Debug Mode, which is our next topic.
|