I'm trying to create a Spring MVC controller that enables creation and editing of a simple domain object (a Player
) using an HTML form. And preferably in a RESTful manner. I've hit a snag with editing when there is an error in the submitted form. I want the client (browser) to display the error messages and the original form, so the user can correct it and resubmit.
But I can't get that to work. On an error I can get the web application to redisplay the original form, but without the error messages. I think because my code redirects to the form page in that case. I tried removing the redirection, but then the web server complains that PUT
is not permitted for the resource. What do I need to do?
Here is the relevant code for my controller:
@Controller
@RequestMapping({
"/player"
})
public class PlayerController {
@RequestMapping(value = "/{id}/edit", method = RequestMethod.PUT)
public String editPlayer(@PathVariable("id")
final long id, @Valid
@ModelAttribute(Model.PLAYER)
final PlayerModel player, final BindingResult result) {
if (!result.hasErrors()) {
final Player playerEntity = playerService.find(id);
playerEntity.setName(player.getName());
playerService.update(playerEntity);
return "redirect:/player/" + id;
} else {
return "redirect:/player/" + id + "/edit";
}
}
@RequestMapping(value = "/{id}/edit", method = RequestMethod.GET)
public String showEditPlayerPage(@PathVariable("id")
final long id, final org.springframework.ui.Model model) {
createModel(id, model);
return View.EDIT_PLAYER;// the player editing page
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String showPlayerPage(@PathVariable("id")
final long id, final org.springframework.ui.Model model) {
// ...
return View.PLAYER;// the read-only view of a player
}
// Other code
}
I have JSR-303 validation annotations on the PersonModel
, which triggers a validation failure if the name
is too short or too long. The HTML for the edit form is this:
<form:form commandName="player" method="PUT">
<fieldset>
<table>
<tr>
<th><label for="player_name">Player Name:</label></th>
<td><form:input path="name" size="64" maxlength="64"
id="player_name" /> <br /> <small
id="player_name_msg">Not empty, but no more
than 64 characters.</small> <form:errors path="name"
class="error" /></td>
</tr>
</table>
<input type="submit" value="Submit"></input>
</fieldset>
</form:form>
Edit:
Just to be clear, everything works OK for the case that the form is valid. I have the servlet filter for translating PUT to POST, and it seems to be working OK.
Edit 2:
Experimentation and tinkering showed that my controller was being executed; the rejection of the PUT happens after execution of my controller. It seems that Spring does not like to have a view-name for the response to a PUT.