Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache Tiles wildcard with Spring WebFlow

Apache Tiles 2.1.3 has a wildcard feature where a tiles definition includes an asterisk:

<definition name="flow/*" extends=".mainTemplate">
    <put-attribute name="header" value="/WEB-INF/jsp/header.jsp"  />
    <put-attribute name="body" value="/WEB-INF/jsp/flow/{1}.jsp"  />
</definition>

It's explained here, but basically this layout is used for any JSP in the "flow" directory.

The problem is Spring Webflow produced infinite recursion with Tiles:

org.springframework.webflow.execution.FlowExecutionException: Exception thrown in state 'createAccount' of flow 'jsp/flow'
Caused by: java.lang.IllegalStateException: Exception occurred rendering view null
Caused by: java.lang.NullPointerException

I wound up inserting many individual Tiles definitions instead of one wildcarded definition (insert frowny face here).

How does Tiles wildcards work with Spring WebFlow?

like image 991
user1071914 Avatar asked Aug 22 '13 22:08

user1071914


1 Answers

Simple fix: You cannot use the default Web Flow view names with wildcarding because you cannot create a wildcard Tiles definition like this:

<definition name="*" extends=".flowTemplate">
    <put-attribute name="header" value="/WEB-INF/jsp/header.jsp"  />
    <put-attribute name="body" value="/WEB-INF/jsp/flow/{1}.jsp"  />
</definition>

The Tiles system goes into a (seemingly) infinite loop if you provide a pure "*" definition like this:

name="*" 

The way to do this is to provide a definition like this:

<definition name="flow/*" extends=".flowTemplate">
    <put-attribute name="header" value="/WEB-INF/jsp/header.jsp"  />
    <put-attribute name="body" value="/WEB-INF/jsp/flow/{1}.jsp"  />
</definition>

And then force your Web Flow view names to that form, like so:

<view-state id="myView" model="myView" view="flow/myView">
    <transition on="back" to="previousView" />
    <transition on="next" to="nextView" />
</view-state>

The default view name is the view id, in this case "myView". You can't give your view an id of "flow/myView" but you can specify the view name separately with

view="flow/myView"

and that will feed the correct value to the Tiles resolver. I'm sure that there are additional wrinkles to Tiles view naming and Web Flow view resolution, but this solved my problem.

Be sure to reference the correct URL (i.e., inject "flow/" as appropriate).

like image 164
user1071914 Avatar answered Sep 28 '22 12:09

user1071914