PDA

View Full Version : onSubmit not being executed during form submission


apcausey
Sep 12th, 2007, 12:11 PM
I am using the portlet MVC (almost identical to the Web MVC). For some reason, when I implement the referenceData method, the onSubmit methods are not called when the form is submitted.

When the page first loads, formBackingObject is called twice (I don't know why twice), followed by referenceData. When the form is submitted, the same thing happens (formBackingObject followed by referenceData) - but neither onSubmit is called. I'm at a loss, because if I comment out the referenceData method and submit the form, the onSubmit methods are called! But I need to use the referenceData method.


public class MovieEditController extends SimpleFormController {

private MovieService movieService;

/*
* (non-Javadoc)
*
* @see org.springframework.web.portlet.mvc.AbstractFormCo ntroller#formBackingObject(javax.portlet.PortletRe quest)
*/
@Override
protected Object formBackingObject(PortletRequest request) throws Exception {

// create and return the MoviePreferences
MoviePreferences moviePreferences = new MoviePreferences(request
.getPreferences());

return moviePreferences;
}

@Override
public void onSubmitAction(ActionRequest request, ActionResponse response,
Object command, BindException error) throws Exception {
MoviePreferences moviePreferences = (MoviePreferences) command;
moviePreferences.savePreferences();
}

@Override
protected ModelAndView onSubmitRender(RenderRequest request,
RenderResponse response, Object command, BindException errors)
throws Exception {
ModelAndView mav = new ModelAndView();
mav.setView(this.getSuccessView());
Map<String, Object> model = new HashMap<String, Object>();
model.put("theaterSet", this.movieService.getAllTheaters(Calendar
.getInstance()));
mav.addAllObjects(model);

return mav;
}

@Override
protected Map referenceData(PortletRequest request) throws Exception {
Map<String, Object> model = new HashMap<String, Object>();
model.put("theaterSet", this.movieService.getAllTheaters(Calendar
.getInstance()));

return model;
}

/**
* @return the movieService
*/
public MovieService getMovieService() {
return this.movieService;
}

/**
* @param movieService
* the movieService to set
*/
public void setMovieService(MovieService movieService) {
this.movieService = movieService;
}

}

<%@ include file="/WEB-INF/jsp/include.jsp"%>
<portlet:actionURL var="actionURL" portletMode="edit" />

<form:form commandName="moviePreferences" action="${actionURL}">

<div style="padding-bottom: 10px">
Select theaters to view movie showtimes.
</div>

<c:forEach var="theater" items="${theaterSet}" varStatus="vs">
<div style="<c:if test='${vs.last}'>padding-bottom: 10px</c:if>">
<form:checkbox path="theaters" value="${theater.id}" />
<c:out value="${theater.name}" />
</div>
</c:forEach>

<input type="submit" value="Save" />

</form:form>

Lori
Sep 12th, 2007, 12:32 PM
I'm not sure about that portlet thing.
Have you checked that the isFormSubmission method works?

apcausey
Sep 12th, 2007, 12:41 PM
Do I need to implement the isFormSubmission method?

Lori
Sep 12th, 2007, 12:45 PM
No, i think not.
But you may want to check what it returns.
The default implementation looks like

return "POST".equals(request.getMethod());


But as i said i have no knowledge of that portlet mvc.

Lori
Sep 12th, 2007, 12:47 PM
AH!

You have to add
method="post"
to your <form>.
Then it should work.
Or you indeed have to overwrite the isFormSubmission method to custom behaviour.

apcausey
Sep 12th, 2007, 01:30 PM
AH!

You have to add
method="post"
to your <form>.
Then it should work.
Or you indeed have to overwrite the isFormSubmission method to custom behaviour.

I added method="post" to the form, and it didn't work. Also, I checked the isFormSubmission value, and it is true when the form is submitted. Somehow, the onSubmit methods still aren't being called. But like I said before, if I remove the referenceData method they ARE called. Weird.

Jörg Heinicke
Sep 12th, 2007, 02:05 PM
I don't think this has anything to do with referenceData() directly. My guess is that you have a binding error (find out if it goes to handleInvalidSubmit()). This binding error might be caused by adding the checkboxes since it has to convert the strings back to Theater instances which it probably can not do out-of-the-box. If my reasoning is correct think about using PropertyEditors.

Joerg

apcausey
Sep 12th, 2007, 02:44 PM
Neither the renderFormSubmission method or renderInvalidSubmit method are getting called when I submit the form. There's no way for me to check if there are errors, since these methods are never called during submission.

The theaters is a String[] that holds the theaterIDs (I guess it should be named theaterIDs so it doesn't sound like it's a collection of objects).

Jörg Heinicke
Sep 13th, 2007, 12:34 AM
Neither the renderFormSubmission method or renderInvalidSubmit method are getting called when I submit the form. There's no way for me to check if there are errors, since these methods are never called during submission.

Try to find out what really happens. handleActionRequest() and handleRenderRequest() of the Controller (http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/web/portlet/mvc/Controller.html) interface are called for sure. But maybe you have mapped your render phase to a different controller and that one gets called?

Joerg

Mark Fisher
Sep 13th, 2007, 12:22 PM
Do you have a unit test for this Controller? If so, you could just pass in a mock ActionRequest to see if the onSubmit* methods are called. That would make it easier to see exactly where the error occurs. It seems like the problem may be due to a binding error on submission - perhaps indirectly caused by the reference data. The referenceData method itself is not called on the form submission processing only when rendering the form view. Therefore if commenting that out causes it to work, then it must be related to how that reference data is bound. Does ${theater.id} resolve to a String? Are the onSubmit* methods invoked when you do not select any of the checkboxes? Does the MoviePreferences class have a setTheaters(String[] theaters) method?

johnalewis
Sep 13th, 2007, 12:40 PM
Creating a unit test for the Controller is a really good idea. Makes debugging this kind of problem much easier.

Another thing you can do is turn up the logging. There should be good output if you set the logging to 'debug' for the org.springframework.web.portlet package.

nyte3k
Sep 22nd, 2007, 12:05 PM
I have the same problem (non portlet). onSubmit will not execute in a SimpleFormController.


Has anyone resolved this issue?

jglynn
Sep 22nd, 2007, 12:10 PM
Is processFormSubmission being called?

If so, do errors exist?

If not, it's possible your request type is not POST. Verify your form is submitting as a POST, not a GET.

nyte3k
Sep 22nd, 2007, 12:28 PM
Is processFormSubmission being called?

If so, do errors exist?

If not, it's possible your request type is not POST. Verify your form is submitting as a POST, not a GET.


no I do not believe processFormSubmission is being called. and my form is POST.

I know at one point i had onSubmit() working with an example controller I created when learning. But for some reason i cannot figure out why it's not working. No obvious exceptions are being thrown or anything.

Jörg Heinicke
Sep 22nd, 2007, 12:52 PM
No obvious exceptions are being thrown or anything.

Usually in that case it's a binding error. These are collected in the Errors/BindException instance. You should have access to it in the JSP (see the error handling tags) or while debugging (toString() tells you the errors).

Joerg

nyte3k
Sep 22nd, 2007, 01:35 PM
Usually in that case it's a binding error. These are collected in the Errors/BindException instance. You should have access to it in the JSP (see the error handling tags) or while debugging (toString() tells you the errors).

Joerg

ahh, that helped. It was a binding error.

by simply adding <form:errors path="*"/>

I was able to see the exact exception. I had custom object in my command, so it was unable to convert it to a string when it attempted to do so.

Thanks!!

Jörg Heinicke
Sep 22nd, 2007, 04:30 PM
I had custom object in my command, so it was unable to convert it to a string when it attempted to do so.

To string is easy but it probably could not do so the other way around ;)
Therefore you can use PropertyEditors (http://static.springframework.org/spring/docs/2.0.x/reference/validation.html#beans-beans-conversion).

Joerg