Tutorial :Keeping request parameters on Spring SimpleFormController with Validator



Question:

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.

Thanks,
Juri


Solution:1

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.


Solution:2

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


Solution:3

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
Previous
Next Post »