How to Integrate Struts Conventions with Tiles while maintaining conventions benefits?
The issue is that conventions links url-to-action-to-result automatically and does this nicely for jsp, velocity and freemarker results. It does not expect to deal with a tiles result.
When using tiles we typically want all our UI actions (as opposed the json/xml service actions) to use tiles but in doing so we lose the convention for the result component and need to use annotations. Annotations allow us to deviate from the expected, but in a large application when expecting to use tiles this is an annoyance. Further conventions allows us to create actions by only specifying a view. We would want to retain such benefit when using tiles as well. To rectify this we need to establish a convention that carries though to the tiles result such that we don't need to use annotations to tie the action to the tiles result and that we can continue to create JSPs without actions classes which will gain the benefits of conventions (no xml) and the benefits of tiles (all the boiler plate is factored into tiles).
How to achieve this?
This is a self answer to help others who wish to address this issue
Here are the steps needed:
The above steps require the following in struts.xml
Custom result-type implementation:
TilesUnknownHandler Implementation:
An example of how to use our "location" string which is in the form of: NameSpace + "#" + ActionName + ".jsp", note this definition
<definition name="REGEXP:(.*)#(.*)" extends="default">
in the following:With this in place you can create JSP's under /WEB-INF/content/someplace/my-action.jsp
Just as you would with conventions AND tiles will decorate it appropriately as well if you create an action class called
com.myapp.action.someplace.MyAction
without any result type this code will execute and the/WEB-INF/content/someplace/my-action.jsp
result would still be rendered.There you have it conventions + tiles with no more annotations (well for the normal case).
NOTES:
REGEXP:(.*)#(.*)
by placing definitions between thedefault
andREGEXP:(.*)#(.*)
definitions. For instance a definition calledauthenticated\(.*)
can be placed between these two definitions. After all if you couldn't do this and all pages had to be tiled the same we really wouldn't be using tiles!