Spring Portlet ResourceRequest Change

Spring Portlet made a change to the way portlets return resource requests.  They changed the default behavior of DispatcherPortlet when handling resource
requests to use PortletRequestDispatcher.forward instead of PortletRequestDispatcher.include; JIRA issue here — SPR-9876.  I’m indifferent about the change.  It seems more people use the ResourceRequest with the .forward, so its good for them I guess.  I mostly use resource requests with small custom jsps, so I use the .include.  But it doesn’t really matter to me aslong as they maintain compatibility, which they did.  If you set renderResourceViewViaInclude property to true(defaults as false) it should work the same as before.

Well, I can’t get my views to render through resource requests anymore after this change.  The only change that was supposed to be needed was adding an init-param into your portlet.xml, but even with that in place my views just return blank.

<init-param>
<name>renderResourceViewViaInclude</name>
<value>true</value>
</init-param>

Another person also suggested to set alwaysInclude to true on the InternalResourceViewResolver in the applicationContext, but that didn’t work for me either.

<bean id=”viewResolver” class=”org.springframework.web.servlet.view.InternalResourceViewResolver”>
<property name=”cache” value=”false”/>
<property name=”alwaysInclude” value=”true”/>
<property name=”viewClass” value=”org.springframework.web.servlet.view.JstlView”/>
<property name=”prefix” value=”/WEB-INF/jsp/”/>
<property name=”suffix” value=”.jsp”/>
</bean>

I’m still trying to figure out why this isn’t working.  Based on the git commit tied to the issue, it looks like aslong as renderResourceViewViaInclude is set to true then the dispatcher should call .include.  Is it not working as intended?  Or is renderResourceViewViaInclude not being set properly?

The culprit has been found! While talking with the person who made the JIRA issue and git commit, it looks like Spring never implemented the renderResourceViewViaInclude flag on DispatcherPortlet(and now rereading the last comment on JIRA I can see that they actually said they weren’t going to). So all resource requests were ALWAYS using .forward.  The fix?  You will have to subclass DispatcherPortlet and override doDispatch to use .include, or set up your own flag.

Hopefully Spring will actually put this the flag into the their portlet library so people won’t have to do this for every portlet that wants a review returned from a resource request.Talking with some other portlet developers, it seems I am in the minority of using resource requests to return views, they are mostly used to return pure json data.  It seems I either need to get with the times or I will have to use my subclassed DispatcherPortlet in all future portlets.

Spring Portlet Handler Mapping Error

Another post about Spring Portlet MVC.  Currently in Spring 3.1.2(and 3.1.1 as far as I can tell) there is a problem with portlet annotation handler mapping apparently due to a flaw in predicate comparison; its documented more in depth in their jira at SPR-9303.  The issue has been reported to have been fixed for Spring 3.1.3, but until that comes out I had to find a work around.

The hard part about diagnosing this bug is that it may or may not affect your portlet depending on how many annotation handlers you have, how they are structured, and in what order they are picked up by Spring.  Many of the portlets we have created haven’t had any problems(or none that we have experienced so far), but one portlet in particular was mapping every single render request to its default mapping.  Someone on stackoverflow has investigated the ordering further and shows exactly why the ordering matters.  Long story short, if the default handler mapping isn’t ordered last then any handler mappings behind it will never get used.

A workaround is simple enough, albeit a little ugly.  Remove the default annotation handler mapping method into its own class and package and have Spring component-scan to register it separately.  Like so:

<context:component-scan base-package=”com.kwilkins.portlets.foo”>
<context:exclude-filter type=”regex” expression=”com.kwilkins.portal.foo.controller.springbug..*”/>
</context:component-scan>
<!– This package temporarily exists due to spring bug; SPR-9303 –>
<context:component-scan base-package=”com.kwilkins.portlets.foo.controller.springbug”/>

Doing this should scan and register the default mapping after everything else already has been.