Steven Mileham – General Geekery

October 21, 2009

Spring frustrations

Filed under: Technology — smileham @ 2:54 pm

I’m currently developing ten tonne of portlets using the Spring Portlet MVC framework.  It’s been a frustrating but rewarding experience.  I’ve been struggling with general documentation and examples for a while, and I wanted to make a quick post about a problem I’ve been having.  Mainly because I found lots of people with similar issues, but no help at a resolution.

I’ve been using the AbstractWizardFormController, and over-riding the

  1.  
  2. public ModelAndView showForm(RenderRequest request, RenderResponse response, BindException errors) throws Exception
  3.  

method to display my view and the
protected Object formBackingObject(PortletRequest request) throws Exception
method to populate my command bean.

My XML looked like this;

  1.  
  2. <bean id="menuSpotlightController" class="uk.co.smileham.cms.controller.edit.SpotlightController">
  3.         <property name="viewName" value="spotlightMenu" />
  4.         <property name="commandName" value="preferenceCommand" />
  5.         <property name="commandClass" value="uk.co.smileham.cms.model.PreferenceCommand" />
  6. </bean>
  7.  

This all seemed fine to me, however whenever I then tried to use the porlet I’d have a huge exception that went something along the lines of;

  1.  
  2. 2009-10-21 14:04:28,765 ERROR [http-8080-Processor19] org.springframework.web.servlet.tags.form.SelectTag – Neither BindingResult nor plain target object for bean name ‘preferenceCommand’ available as request attribute
  3. java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name ‘preferenceCommand’ available as request attribute
  4.         at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
  5.         at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:172)
  6.         at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:192)
  7.         at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:158)
  8.         at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:121)
  9.         at org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:379)
  10.         at org.springframework.web.servlet.tags.form.SelectTag.writeTagContent(SelectTag.java:198)
  11.         at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:90)
  12.         at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:77)
  13.         at org.apache.jsp.WEB_002dINF.jsp.spotlightMenu_jsp._jspService(spotlightMenu_jsp.java:658)
  14.         at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
  15.         at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
  16.         at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
  17.         at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
  18.         at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
  19.         at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
  20.  

After much frustration I discovered that the problem was that the “preferenceCommand” was being set in the model, but then being overridden by a new model in my showForm() method.

The solution was to read the documentation (funny that) and eventually found that when using the AbstractFormController you should not directly create a new ModelAndView object to return but instead get the current model from the “BindException errors” variable that has been passed in and then “return super.showForm(request, errors, viewName);”

So my final showForm method went from;

  1.  
  2. public ModelAndView showForm(RenderRequest request, RenderResponse response, BindException errors) throws Exception {
  3.                 ModelAndView mav = new ModelAndView(viewName);         
  4.                 return mav;
  5.         }
  6.  

to

  1.  
  2. public ModelAndView showForm(RenderRequest request, RenderResponse response, BindException errors) throws Exception {
  3.                 Map<String,Object> model = errors.getModel();
  4.                 return super.showForm(request, errors, viewName);
  5.         }
  6.  

That may all seem like giberish, but hopefully it’ll mean that someone else seeing the same problem might figure out what’s going on sooner! (That and I shouldn’t fall into this problem again any time soon now.)

1 Comment »

  1. Phew, glad I don’t have to use Java. Good job on fixing it.

    Comment by Steve Johnstone — October 21, 2009 @ 3:38 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress