コンテキスト
Category
2 つのエンティティーとEmail
(NtoM)の間に単純な関連付けがあります。それらを閲覧および管理するためのWebインターフェイスを作成しようとしています。カテゴリを参照し、そのカテゴリに電子メールを追加するには@RequestMapping
、カテゴリ ID (UUID) でラップされたコントローラーを使用するため、すべてのコントローラー アクションは、パスで指定されたカテゴリのコンテキストで常に実行されます。
@ModelAttribute
コントローラースコープ全体のコンテキストカテゴリをプリロードするために使用します。
問題
このアプローチは、リストとフォームの表示に適していました。ただし、フォームの送信では失敗します。少しデバッグした後、フォーム データがカテゴリ@ModelAttribute
パラメータをオーバーライドすることがわかりました。
私のコードでは、メソッドsave()
は実際にはメソッドでcategory
ロードされたモデル属性ではありませんがaddCategory()
、フォームデータが入力されています(email
モデルも入力されており、それは正しいです)。
フォーム データを特定の .xml にのみバインドできるようにするソリューションを探しています@ModelAttribute
。
引数の順序が重要であるというSpring MVCのドキュメントを読みましたが、例に応じて順序付けしましたが、期待どおりに機能しません。
コード
これが私のコントローラーです:
@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());
}
}
念のため、ここにもフォームコードがあります:
<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>
注:複数の が POST から取得されるのは望ましくありません@ModelAttribute
。フォーム モデルと以前に生成された属性を何らかの形で区別したいだけです。