Tutorial :Keeping request parameters on Spring SimpleFormController with Validator


I hope I'll be able to explain this properly. I'm developing a portlet for Liferay by using Spring. It's a pinboard system. So I have a view (Jsp) which shows the detail of a certain pinboard entry, given its id. Furthermore there is a link which goes to an AddCommentController for adding a new comment to the pinboard entry the user is currently watching at. The AddCommentController extends Spring's SimpleFormController and has also a validator attached to it:

<bean id="addCommentController" class="com.lifepin.controllers.AddCommentController" parent="lifePinControllerTemplate">      <property name="formView" value="addComment" />      <property name="successView" value="viewEntryDetail" />      <property name="validator" ref="commentValidator"/>  </bean>  

The validator is really simple and looks as follows:

public class CommentValidator implements Validator {        public boolean supports(Class clazz) {          return clazz.equals(Comment.class);      }        public void validate(Object obj, Errors validationError) {          ValidationUtils.rejectIfEmptyOrWhitespace(validationError, "content", "err.content.empty", "This value is required");      }    }  

Now the view where the user can enter his comment has two buttons, Save and cancel. Here are the two generators for the according urls.

<portlet:actionURL var="actionUrl">      <portlet:param name="action" value="addComment"/>      <portlet:param name="pinboardEntryId" value="${param.pinboardEntryId}"/>  </portlet:actionURL>    <portlet:renderURL var="cancelUrl">      <portlet:param name="action" value="viewPinboardEntry"/>      <portlet:param name="pinboardEntryId" value="${param.pinboardEntryId}"/>  </portlet:renderURL>  

In the onSubmitAction of the AddCommentController I read out the parameter (see the 1st actionURL above) and pass it to the ActionResponse s.t. in the detail view of the pinboard entry I can again load the entry and display it.

public class AddCommentController extends SimpleFormController{     ...     @Override     protected void onSubmitAction(ActionRequest request, ActionResponse response, Object command, BindException bindException)              throws Exception {          long pinboardEntryId = PortletRequestUtils.getLongParameter(request, ParameterNameConstants.PINBOARDENTRY_ID, -1);        ...     }     ...  }  

This all works fine, except when a validation error occurs. In that case I loose the "pinboardEntryId" parameter from the URL, and I don't have any way to read that parameter in the CommentValidator to pass it to the response again since I don't have any PortletRequest or response.

For now I solved this problem by storing the id on the session and by retrieving it from there. I wanted to ask however if some of you has an alternative solution without having to use the session. I'm quite sure there is one.



An even easier solution is to set the renderParameters property. The renderParameters property is an array of parameter names that SimpleFormController will always forward. For example:

    <bean id="addCommentController" class="...">           ....           <property name="renderParameters">             <list>               <value>pinboardEntryId</value>             </list>           </property>      </bean>  

This will cause the 'pinboardEntryId' parameter to be passed every time without any additional code.


On validation errors showForm(..) gets called again. You could overwrite this method and manipulate Request and Response as you like.


I first tried the showForm(..) approach suggested by Oliver Gierke (thanks for the feedback) but that didn't work out as expected. The showForm(..) wants to return a new ModelAndView which I don't want to care since that should be done by the onSubmitAction(...).

The right approach is to override the

@Override  protected void processFormSubmission(ActionRequest request, ActionResponse response, Object command, BindException errors){    ...  }  

There, all the needed information is available. I can check now the BindingException whether there have been validation errors by using errors.hasErrors(). If that's the case, I can read the needed parameters and forward them to the response to have them on the form again. Otherwise I just call the onSubmitAction(..), passing the needed parameters such as the request, reponse etc.. which I have available in the processFormSubmission.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »