Hello.

I understand now why a filter may be a better solution to set the request attribute and force Tiles to use include calls. This let the ViewPreparer available for specific Tiles needs.

I think It's likely impossible anyway in portlets, since, for what I know, there's no standard way to get the servlet request from the portlet requests (action, render), and attributes set on these seem to be local and not visible from Tiles... Furthermore, as you say, this should be done on every portlet, and thus tedious !

The last point I want to check is the way a pure servlet filter will be activated depending on the portlet container or the application server, and the possible interferences between distinct portlet web applications...

About Spring MVC : I'm not sure, and perhaps recent versions provide better integration with Portlet 2.0. I've read things about new annotations to map events, for example, to controllers, and I've had a look to the 3.1, and nothing of that appear... I have to look at it better.

Thanks again.
Regards.

Ephemeris Lappis

Le 15/08/2012 18:53, Nicolas LE BAS a écrit :
On 12-08-14 05:35 PM, Ephemeris Lappis wrote:
Spring MVC [...]. For information, its poor support for
Portlet 2.0 makes it a limited candidate for me...

Really? According to the spring guys, it is designed specifically for Portlet 2.0. Just out of curiosity, what makes you think it's so poor?

Not that I'm suggesting it as an alternative; Tiles with Spring MVC Portlet will have that same bug we're discussing here anyway...

The ViewPreparer workaround seems to work, but I'm not completely
convinced that it will do it in all cases.

I don't understand what you mean about the dispatcher servlet and why I
should prefer the filter alternative. Does it work better, particularly
for portlet applications ?

Let's look at an example:
<tiles-definitions>
    <definition name="def1" template="/layout1.jsp">
        <put-attribute name="content" value="/content1.jsp"/>
        <put-attribute name="data" value="/data1.jsp"/>
    </definition>
    <definition name="def2" template="/layout2.jsp">
        <put-attribute name="content" value="/content2.jsp"/>
        <put-attribute name="data" value="/data2.jsp"/>
    </definition>
    <definition name="def11" extends="def1">
        <put-attribute name="content" value="/content11.jsp"/>
    </definition>
</tiles-definitions>
And let's say we're calling portletContext.getRequestDispatcher("/def11.tiles").include(request,response);

The execution flow goes as follow:
- The platform maps /def11.tiles to TilesDispatchServlet (*.tiles)
- TilesDispatcherServlet finds out the appropriate definition and calls TilesContainer.render("def11", request, response); - The TilesContainer sets the tiles attributes (/content11.jsp,/data1.jsp) and forwards to the template (/layout1.jsp). Here is the bug: we want it to include the template instead.
- The template includes the attributes.

As a workaround in order to force Tiles into including the template, we just have to set the appropriate attribute before the forwarding happens:
request.setAttribute(ServletUtil.FORCE_INCLUDE_ATTRIBUTE_NAME,
Boolean.TRUE);

This can happen at 3 times that I can think of:

1. in the Portlet, before we call requestDispatcher.include, by setting the attribute on the RenderRequest. But this has to be done in every portlet.

2. in a ServletFilter mapped to *.tiles (same as TilesDispatchServlet), that will be called before the execution flow reaches TilesDispatchServlet.

3. in a ViewPreparer attached to the definition, that will be called before the template is processed. But this has to be declared on every root definition (def1 and def2, def11 will inherit it from def1). Additionally, if you declare another ViewPreparer on def11 for some reason, it will replace the inherited "force-include" ViewPreparer for this specific definition.

Therefore 2. is the cleanest workaround IMHO. If you call Tiles only from portlets, you want the fix to be applied once and for all, without polluting your actual business code.

Thanks for your help and advices.

Thanks for your comments and insight!

Nick.


Reply via email to