FINN tech blog

tech blog

the ultimate view — Tiles-3

A story of getting the View layer up and running quickly in Spring…

Since the original article, parts of the code has been accepted upstream, now available as part of the Tiles-3 release, so the article has been updated — it’s all even simpler!


Based upon the Composite pattern and Convention over Configuration we’ll pump steroids into
   a web application’s view layer
      with four simple steps using Spring and Tiles-3
         to make organising large complex websites elegant with minimal of xml editing.



 




Background

At FINN.no we were redesigning our control and view layers. The architectural team had decided on Spring-Web as a framework for the control layer due to its flexibility and for providing us a simpler migration path. For the front end we were a little unclear. In a department of ~60 developers we knew that the popular vote would lead us towards SiteMesh. And we knew why – for practical purposes sitemesh gives the front end developer more flexibility and definitely less xml editing.
But sitemesh has some serious shortcomings…

SiteMesh shortcomings:
  • from a design perspective the Decorator pattern can undermine the seperation MVC intends,
  • requires all possible html for a request in buffer requiring large amounts of memory
  • unable to flush the response before the response is complete,
  • requires more overall processing due to all the potentially included fragments,
  • does not guaranteed thread safety, and
  • does not provide any structure or organisation amongst jsps, making refactorings and other tricks awkward.

One of the alternatives we looked at was Apache Tiles. It follows the Composite Pattern, but within that allows one to take advantage of the Decorator pattern using a ViewPreparer. This meant it provided by default what we considered a superior design but if necessary could also do what SiteMesh was good at. It already had integration with Spring, and the way it worked it meant that once the Spring-Web controller code was executed, the Spring’s view resolver would pass the model onto Tiles letting it do the rest. This gave us a clear MVC separation and an encapsulation ensuring single thread safety within the view domain.

“Tiles has been indeed the most undervalued project in past decade. It was the most useful part of struts, but when the focus shifted away from struts, tiles was forgotten. Since then struts as been outpaced by spring and JSF, however tiles is still the easiest and most elegant way to organize a complex web site, and it works not only with struts, but with every current MVC technology.” – Nicolas Le Bas

Yet the best Tiles was going to give wasn’t realised until we started experimenting a little more…

18 comments

  1. Sam says:

    This is a great article. Is there an example app to go along with it? I must be missing some details because I can’t get the fallback pattern to work.

  2. mck says:

    Sam,
    it would be best if you could provide some more information about what error messages you are failing with, and to send it to users@tiles.apache.org (where i’ll help you out further).

  3. Bill says:

    mck,

    Thanks for the write up. It seems to be the only comprehensive Spring, Tiles 3 one out there. I am just working through it now and noticed that on page 4 you have put-list-attribute outside of the definition . I think this violates the DTD.

  4. mck says:

    Thanks for spotting the error Bill.
    It has been corrected now.

  5. Eric B says:

    Thanks for the write up. But I’m a little confused as to where the dependency injection is working on the template level. Are you able to also post an example of the actual templates (ie: template.jsp or view_body.jsp, etc…) so we can better see how/where the dependency injection is taking place?

  6. mck says:

    Eric, if you are referring to definition injection (page 5 / step 3), then this happens by when override getDefinitions() in your DefinitionsFactory subclass. See the code on page 5. Note that your TilesContainerFactory subclass must also override instantiateDefinitionsFactory(..) so to return your DefinitionsFactory subclass.

  7. Alzemanuel says:

    This is a great article, I have been trying to implement this using Spring 3.2,
    Have some issues, would have been great if you provide source code.

    Thanks for the insight though.

  8. Praveen says:

    Hello mck,

    Thank for the article.

    Some articles(on web) comparing the Apache Tiles with Thymeleaf and their conclusion is Thymeleaf is a head then Apache Tiles. Please provide your views on this comparison and please provide advantages of Apache Tiles over Thymeleaf.Which will help me to use in my new project.

    Project technologies : Spring MVC 3, BootStrap 3, JQuery.

    Thanks a lot,
    Praveen

  9. mck says:

    Tiles is the templating system, providing an abstraction layer of the templating languages you use.
    Thymeleaf is a templating language.

    Tiles allows you to use multiple templating languages/scripts in your view, for example you could implement a thymeleaf tiles render and then introduce thymeleaf into your application where appropriate or slowly in a migration process.

    I think the comparison is therefore a little apples and oranges. Take a closer look at your use case.

  10. Eric B says:

    Hi Mck,

    I am trying to integrate your blog in a Spring 3.2.4 application, but it appears that Spring 3.2.4 does not have the same resolver/context/etc classes that you posted. I know you have a link where to d/l them, but if I read through SPR-8825, it marks everything as having been fixed in 3.2RC, which means that it should already be in 3.2.4. Additionally, if I read through the comments, it points to TREQ-12, which indicates a different class (ie: SpringWildcardServletTilesApplicationContext for the context).

    Are you able to update this blog/example with the most recent requirements for Spring 3.2.x and Tiles 3?

    Tx,

    Eric

  11. Eric B says:

    Hi Mck,

    The more I try to incorporate your suggestions, the more conflicts I run into. For instance, in the Tiles3 documentation, it clearly specifies ( http://tiles.apache.org/framework/tutorial/advanced/wildcard.html) that: As a prerequisite for using prefixes, you need to have CompleteAutoloadTilesContainerFactory enabled. Where a prefix is “REGEXP”. But in your blog, you are only using the Factory to extend the BasicTilesContainerFactory and not the CompleteAutoloadTilesContainerFactory. However, simply enabling the CompleteAutoloadTilesContainerFactory seems to break other things in your examples.

    Are you able to update this blog such that it is compatible with the latest Spring 3.2.x branch?

    Thanks,

    Eric

  12. mck says:

    Eric,

    …in the Tiles3 documentation… a prerequisite for using prefixes, you need to have CompleteAutoloadTilesContainerFactory enabled.

    Using CompleteAutoloadTilesContainerFactory is the easiest way to get running wildcards with prefixes, for example if you want both wildcard and regexp.
    The article posts to the tutorial you’ve linked to with the intention of it being prerequisite information. But i can see that this is rather clumsy and too subtle. Thanks for pointing that out and i’ve updated the article accordingly, it would be great to hear whether you think the improvement helps!

  13. mck says:

    Eric,

    it appears that Spring 3.2.4 does not have the same resolver/context/etc classes that you posted

    you are very correct! As SPR-8825 got ironed out (sometime after the article was written) we got rid of SpringWildcardServletTilesApplicationContext. I’ve updated the article, thanks again for pointing errors out.

  14. Eric B says:

    Mck,

    Thanks for the updates to your blog; it is definitely more clear. I had somewhat figured out those differences as well, but still run into problems with your example. I already posted my findings to the Apache Tiles mailing list and created an issue Tiles-572 (https://issues.apache.org/jira/browse/TILES-572).

    Basically, I keep getting an error message: “java.lang.IllegalStateException: A matching list-attribute name=”myopts” must be defined.”.

    Searching the web finds others that have the same issue. From what I can ascertain from the Tiles core, contexts are being pushed on a stack (although not sure which contexts), but these contexts are empty (both attributes=null and cascadedAttributes=null). Consequently, when the OptionsRenderer tries to retrieve values from this context (which is blank), it fails and throws this error.

    Do you have a functional example of the FinnTilesInitialiser that you can share?

    Thanks,

    Eric

  15. mck says:

    Basically, I keep getting an error message: “java.lang.IllegalStateException: A matching list-attribute name=”myopts” must be defined.”.

    This problem is being discussed between TILES-572 and the mailing list.

    Otherwise i’ll see what we can do above publishing a simple working version of it all on github (but i can’t give you any eta on that).

  16. Enrique says:

    Hi mck,

    I have a working example about your post, and based on it. I will publish it during next week on github.

  17. [...] finished creating an example about Apache Tiles 3 and Spring Framework integration based on “The Ultimate View” article you can find at “Tech Blog“. It’s a simple working example you can [...]

  18. Ralph says:

    The Link to the ViewPreparer (on page 1) is brocken. It seam that the page has been moved to: http://tiles.apache.org/framework/tutorial/advanced/preparer.html

    (EDIT: thanks for spotting it. has been fixed now.)

Leave a Reply

Fork me on GitHub casus telefon telefon dinleme casus telefon telefon dinleme casus telefon telefon dinleme casus telefon telefon dinleme casus telefon telefon dinleme