Spring MVC: le fait d'Avoir de multiples @ModelAttribute en forme de manipulation de l'action
Le contexte
J'ai une simple association entre les deux entités - Category
et Email
(NtoM). Je suis en train de créer l'interface web pour la navigation et de leur gestion. Pour parcourir la catégorie et d'ajouter des e-mails dans cette catégorie, j'utilise le contrôleur enveloppé avec @RequestMapping
avec l'ID de la catégorie (UUID), de sorte que toutes les actions du contrôleur sont toujours en prenant place dans le contexte de la catégorie spécifiée avec chemin d'accès.
- Je utiliser @ModelAttribute
de pré-charger le contexte de catégorie pour l'ensemble du contrôleur de portée.
Le problème
Cette approche a bien fonctionné pour l'inscription et pour l'affichage des formes. Cependant, il échoue sur le formulaire de soumission - après le débogage un peu, j'ai découvert que les données de formulaire remplace ma catégorie @ModelAttribute
paramètre.
Dans mon code, dans la méthode save()
la category
n'est pas vraiment le modèle de l'attribut chargé avec addCategory()
méthode, mais est rempli avec les données du formulaire (email
modèle est aussi peuplée, et que c'est correct).
Je suis à la recherche de la solution qui me permettra de lier les données de formulaire à seulement certains @ModelAttribute
.
J'ai lu dans Spring MVC documentation que l'ordre des arguments de questions, mais je les ai commandés en conséquence à des exemples et encore cela ne fonctionne pas comme prévu.
Le code
Voici mon controller:
@Controller
@RequestMapping("/emails/{categoryId}")
public class EmailsController
{
@ModelAttribute("category")
public Category addCategory(@PathVariable UUID categoryId)
{
return this.categoryService.getCategory(categoryId);
}
@InitBinder
public void initBinder(WebDataBinder binder)
{
binder.registerCustomEditor(Set.class, "categories", new CategoriesSetEditor(this.categoryService));
}
@RequestMapping(value = "/create", method = RequestMethod.GET)
public String createForm(@ModelAttribute Category category, Model model)
{
//here everything works, as there is just a single @ModelAttribute
return "emails/form";
}
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(
@ModelAttribute @Valid Email email,
BindingResult result,
Model model,
@ModelAttribute("category") Category category
) {
//saving entity, etc
//HERE! problem is, that response is bound BOTH to `email' and `category' model attributes
//and overrides category loaded in `addCategory()' method
return String.format("redirect:/emails/%s/", category.getId().toString());
}
}
Juste au cas où, ici, est également le code du formulaire:
<form:form action="${pageContext.request.contextPath}/emails/${category.id}/save" method="post" modelAttribute="email">
<form:hidden path="id"/>
<fieldset>
<label for="emailName"><spring:message code="email.form.label.Name" text="E-mail address"/>:</label>
<form:input path="name" id="emailName" required="required"/>
<form:errors path="name" cssClass="error"/>
<label for="emailRealName"><spring:message code="email.form.label.RealName" text="Recipient display name"/>:</label>
<form:input path="realName" id="emailRealName"/>
<form:errors path="realName" cssClass="error"/>
<label for="emailIsActive"><spring:message code="email.form.label.IsActive" text="Activation status"/>:</label>
<form:checkbox path="active" id="emailIsActive"/>
<form:errors path="active" cssClass="error"/>
<form:checkboxes path="categories" element="div" items="${categories}" itemValue="id" itemLabel="name"/>
<form:errors path="categories" cssClass="error"/>
<button type="submit"><spring:message code="_common.form.Submit" text="Save"/></button>
</fieldset>
</form:form>
Remarque: je ne veux pas de multiples @ModelAttribute
s à venir à partir de POST, je veux juste vous distinguer en quelque sorte de modèle de formulaire à partir d'précédemment généré attribut(s).
OriginalL'auteur Rafał Wrzeszcz | 2013-10-08
Vous devez vous connecter pour publier un commentaire.
Je ne suis pas sûr de comprendre entièrement le problème, mais pour moi, il semble que vous voulez catégorie d'objets présents dans le modèle lors de l'affichage de la forme, mais ne voulez pas qu'il soit changé avec le post de formulaire?
Lorsque vous spécifiez @ModelAttribute (les"catégories") dans la liste d'arguments en gros, vous dites spring MVC pour lier les données de formulaire à l'objet à l'aide du paramètre nom de "catégories".
Si vous ne voulez pas l'objet à être lié juste le laisser dehors à partir de la liste des paramètres. Si vous avez besoin de l'objet d'origine dans la méthode de gestionnaire d'extraire manuellement en appelant addCategory et de fournir id mappée avec @PathVariable:
(PS. Si vous vous inscrivez à un convertisseur qui convertit le Long d'une Catégorie à l'aide categoryService vous pouvez aussi mettre
@PathVariable("categoryId") Category category
à la carte de la Catégorie de l'objet à la variable de chemin d'accès au lieu de l'UUID, si vous souhaitez que jeter un regard à 7.5.5 la Configuration d'un ConversionService)(EDIT: suppression de la suggestion de nom de modèle différemment que cela ne l'aidera pas comme indiqué dans les commentaires, et ajout de l'exemple)
Personnellement, si j'avais besoin de ce genre de comportement (un objet qui doit être présent dans le formulaire lors de l'affichage de la forme, mais n'est pas lié à elle au moment où le formulaire est posté) je ne voudrais pas utiliser ModelAttribute méthode annotée pour alimenter le modèle. Au lieu de cela, j'avais remplir le modèle manuellement lors de l'affichage de la forme. C'est un peu plus de code (enfin, une ligne, en fait), mais est moins magique et plus facile à comprendre.
categories
comme le nom de l'attribut, j'utilisecategory
, qui ne se chevauchent pas avec n'importe quel champ de formulaire. Juste que les champs de formulaire sont tous liés à la catégorie de l'objet (les deux objets ontname
propriété, par exemple et au Printemps se lie champ de formulaire de la valeur à la foiscategory.name
etemail.name
). Et pour le remplissage de "manuellement lors de l'affichage de la forme" approche - j'ai besoin d'catégorie dans la présentation des actions de manutention pour la redirection (note de la dernière ligne desave()
action).Vous avez raison, le fait de renommer le modèle ne fonctionne pas alors que le Printemps se lie sur propriétés. J'ai supprimé cette de réponse et édité réponse avec des exemples de la façon d'obtenir de la catégorie d'origine dans save ().
Avait de l'espoir pour le résoudre de manière différente, mais votre solution est en fait encore plus compact - en fait, je n'ai pas besoin de tout objet. Semble un peu étrange que de tels cas d'utilisation ne sont pas pris en charge (ou au moins, je ne peux pas savoir comment) d'ici le Printemps, mais merci beaucoup pour l'aide avec cela.
Si vous avez seulement besoin de l'id de redirection et non pas pour certains types de traitement dans l'action save, vous pouvez simplement retourner "redirect:/emails/{categoryId}/" et le Printemps va remplacer {categoryId} avec l'identification réelle de la demande. Dans ce cas, vous pouvez supprimer la catégorie à partir de la méthode de la liste d'arguments tout à fait.
OriginalL'auteur Kresimir Nesek