SpringMVCで@ModelAttributeアノテーションを使用する方法
以下は「SpringMVCでデータ送信(POST)する 」で作成したコントローラです。
@ModelAttributeを使っていませんがmodel.addAttribute~でアクションフォームのインスタンスを格納していました。
package jp.co.confrage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("sample")
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping(value = "home", method = RequestMethod.GET)
public String home(Model model) {
logger.info("Welcome Sample Page.");
model.addAttribute(new HomeForm());
return "home";
}
}
homeメソッドの引数にアクションフォームを変更し、model.addAttribute~の行をコメントアウトします。
package jp.co.confrage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("sample")
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping(value = "home", method = RequestMethod.GET)
public String home(Model model,HomeForm form) {
logger.info("Welcome Sample Page.");
// model.addAttribute(new HomeForm());
return "home";
}
}
引数で指定することで、明示的にmodel.addAttributeする必要がなくなります。
裏で、model.addAttribute(new HomeForm());が実行されているようなイメージです。
※model.addAttribute(“homeForm”,new HomeForm());と同じ
JSP側はなにも変更せずに、modelAttribute属性にはhomeFormを指定しています。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<P> Welcome Sample Page. </P>
<spring:url value="/sample/post" var="action" />
<form:form action="${action}" method="post" modelAttribute="homeForm">
<form:label path="keyword">入力</form:label>
<form:input path="keyword" />
<form:errors path="keyword" cssStyle="color:red" />
<input type="submit" value="送信" />
</form:form>
</body>
</html>
では@ModelAttributeアノテーションを使用してみます。引数の前に記述します。
package jp.co.confrage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("sample")
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping(value = "home", method = RequestMethod.GET)
public String home(Model model,@ModelAttribute("aForm")HomeForm form) {
logger.info("Welcome Sample Page.");
// model.addAttribute(new HomeForm());
return "home";
}
}
このままだと「Neither BindingResult nor plain target object for bean name ‘homeForm’ available as request attribute」とJSP側でエラーが出るので、modelAttribute属性にaFormと記述します。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<P> Welcome Sample Page. </P>
<spring:url value="/sample/post" var="action" />
<form:form action="${action}" method="post" modelAttribute="aForm">
<form:label path="keyword">入力</form:label>
<form:input path="keyword" />
<form:errors path="keyword" cssStyle="color:red" />
<input type="submit" value="送信" />
</form:form>
</body>
</html>
これで属性名を変更して正常に動作します。
メソッドに対して@ModelAttributeアノテーションを指定できる
@ModelAttributeアノテーションをメソッドの上に指定するとまた意味合いが違ってきます。
package jp.co.confrage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("sample")
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@AutoWired
HomeForm bean; // フォームの値を入れたいなら@AutoWiredでDIする
@RequestMapping(value = "home", method = RequestMethod.GET)
public String home(HomeForm hf) { // 引数に指定してあげることでセッターが呼ばれる
logger.info("Welcome Sample Page.");
return "home";
}
@ModelAttribute
public HomeForm setForm(){ // メソッド名は何でもよい
return this.bean;
}
}
setFormメソッドが実行されインスタンスが返されます。その次にhomeメソッドが実行されて、これも正常に動作します。
※この時、JSP側のmodelAttribute属性にはhomeFormを指定すること(アクションフォーム(ビーン)クラスのキャメルケースにしておく必要がある)
@ModelAttributeアノテーションの役割とは
上記のとおり、@ModelAttributeアノテーションでjspとアクションフォーム(ビーンって言えばわかりやすい?)の指定した別名で連携をするだけのアノテーションです。
KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント