Spring MVCの主な機能
前置きが長くなったが、それでは早速Spring MVCの機能についてみていく。現在のSpring MVCでは、遷移先の情報は設定ファイルではなく、コントローラクラスに記述する。また、Spring 3.0からは、RESTスタイルのURLが簡単に実現出来るようになっている。
例えば、JSPからhttpのgetで送信する場合は以下のようになる。
JSP
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<spring:url value="user/{userId}" var="userUrl">
<spring:param name="userId" value="${userId}"/>
</spring:url>
<a href="${fn:escapeXml(userUrl)}">ユーザ</a>
上記の例では、URLは、「http://localhost:8080/mvc-sample/user/0001」のようになる。<spring:url>タグのvalue属性にはURLを記述する。{変数名}で動的に値を変更することが出来る。{変数名}の値は、<spring:param>タグのname属性で設定した値が使用される。<spring:param>タグのvalue属性には、EL式を利用して値を取得している。<spring:url>タグのvar属性に指定した値を利用して、<a>タグのhref属性に指定する。不正な値が設定されないようにJSTLの${fn:escapeXml}で文字列をエスケープしている。
リクエストを受け取るコントローラクラスは以下のようになる。
コントローラ
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/user/{userId}", method = RequestMethod.GET)
public String show(@PathVariable String userId, ModelMap modelMap) {
modelMap.addAttribute("user", userService.show(userId));
return "user/show";
}
}
コントローラクラスには、@Controllerを付与する必要がある。このとき、 Springのbean定義ファイルには「<mvc:annotation-driven />」という1行が必要になる。@RequestMappingは、value属性でURLのパスやmethod属性でhttpのメソッドを指定する。value属性には、{変数名}で動的な値も設定することが出来る。メソッドアノテーションに指定している@PathVariableは、@RequestMappingのvalue属性で指定した動的なURLの{変数名}部分がバインドされる。メソッド引数のModelMapは、次の画面に引き継ぎたいパラメータがあれば使用する。戻り値にuser/showを指定しているので、WEB-INF/views/user/show.jspに遷移する。show.jspでは、以下のようにEL式で値を取得することが出来る。
<c:out value="${user.userId}"/>
JSPからhttpのPOSTで送信する場合は以下のようになる。ここではあわせて、入力チェックも行う例を示す。入力チェックは、Spring 3.0からアノテーションで入力チェックを設定するBean Validationが使えるようになっている。なお、Bean Validationを使用するには、以下の設定をpom.xmlに追加する。
pom.xmlへの追加
No | Group Id | Artifact Id | Version |
---|---|---|---|
1 | javax.validation | validation-api | 1.0.0.GA |
2 | org.hibernate | hibernate-validator | 4.0.2.GA |
3 | joda-time | joda-time | 1.6 |
JSP
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<form:form modelAttribute="user" method="post">
<p>
<form:label path="userId" for="userId">ユーザID</form:label>
<form:input path="userId"/><form:errors path="userId" cssClass="errors"/>
</p>
<p>
<form:label path="userName" for="userName">ユーザID</form:label>
<form:input path="userName"/><form:errors path="userName" cssClass="errors"/>
</p>
<p>
<form:label path="address" for="address">アドレス</form:label>
<form:input path="address"/><form:errors path="address" cssClass="errors" />
</p>
<input type="submit"/>
</form:form>
JSPの記述には、便利なSpringのformタグを使用している。<form:form>タグのmodelAttribute属性で使用するDTOを指定する。その為、<form:input>などで指定しているuserIdなどの変数を持っている必要がある。<form:errors>タグは、エラー時にエラーメッセージを表示する。入力チェックは、DTOにアノテーションを付与することで行う。
コントローラクラスは以下のようになる。
コントローラ
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(method = RequestMethod.POST)
public String create(@Valid User user, BindingResult result,
ModelMap modelMap) {
if (result.hasErrors()) {
modelMap.addAttribute("user", user);
return "user/create";
}
userService.create(user);
return "user/show";
}
}
コントローラクラスでは、メソッド引数として@Validを指定する。BindingResultに入力チェックされた結果が格納されているので、チェック結果に応じてハンドリングを行う。
なお、入力エラー時のメッセージは、デフォルトでは、hibernate-validator-4.0.2.GA.jarのorg.hibernate.validatorに含まれるValidatorMessages.propertiesのメッセージが使用される。ここには日本語用のメッセージがないため、ValidationMessages_ja.propertiesというファイルを作成してクラスパス上に配置する必要がある。設定例を以下に示すので参考にしてほしい。キーは、「javax.validation.constraints.[入力チェックルール].message」となる。これらは、JSR-303というJava標準で決められているルールに準拠している。
ValidationMessages_ja.propertiesの記述例
javax.validation.constraints.AssertFalse.message=不正な値が入力されました。
javax.validation.constraints.AssertTrue.message=不正な値が入力されました。
javax.validation.constraints.DecimalMax.message={value}より同じか小さい値を入力してください。
javax.validation.constraints.DecimalMin.message={value}より同じか大きい値を入力してください。
javax.validation.constraints.Digits.message=整数{integer}桁以内、小数{fraction}桁以内で入力してください。
javax.validation.constraints.Future.message=未来の日付を入力してください。
javax.validation.constraints.Max.message={value}より同じか小さい値を入力してください。
javax.validation.constraints.Min.message={value}より同じか大きい値を入力してください。
javax.validation.constraints.NotNull.message=値が未入力です。
javax.validation.constraints.Null.message=値は未入力でなければいけません。
javax.validation.constraints.Past.message=過去の日付を入力してください。
javax.validation.constraints.Pattern.message="{regexp}"にマッチしていません。
javax.validation.constraints.Size.message=サイズは{min}から{max}の間の値を入力してください。
org.hibernate.validator.constraints.Email.message=E-mail形式で入力してください。
org.hibernate.validator.constraints.Length.message=文字の長さは{min}から{max}の間で入力してください。
org.hibernate.validator.constraints.NotEmpty.message=値が未入力です。
org.hibernate.validator.constraints.Range.message={min}から{max}の間の値を入力してください。
アノテーションの設定例
@AssertFalse
private boolean assertFalse;
@AssertTrue
private boolean assertTrue;
@DecimalMax(value="5.5")
private BigDecimal decimalMax;
@DecimalMin(value="5.5")
private BigDecimal decimalMin;
@Digits(integer=3,fraction=2)
private BigDecimal digits;
@Future
@DateTimeFormat(pattern="yyyy/MM/dd")
private Date futureDate;
@Max(value=3)
private int max;
@Min(value=3)
private int min;
@NotNull
private String notNull;
@Null
private String nul;
@Past
@DateTimeFormat(pattern="yyyy/MM/dd")
private Date pastDate;
@Pattern(regexp="[a-z]+")
private String pattern;
@Size(min=3,max=5)
private String size;
@Email
private String email;
@Length(min=3,max=5)
private String length;
@NotEmpty
private String notEmpty;
@Range(min=3,max=5)
private BigDecimal range;
* * *
本稿ではSpring MVCの基本的な機能について紹介した。最新のMVCフレームワークとしては、格段目立った機能がないもののシンプルで使いやすいフレームワークとなっている。フレームワークを検討している方は選択肢の一つに加える価値はあるだろう。
執筆者紹介
石橋 稔章(ISHIBASHI Toshiaki) - DTS
JavaEEのフレームワーク開発などを経験した後、業務システム向けアーキテクトに。現在は、金融系の大規模プロジェクトに参画し、リリースに向けて奮闘中。最近は温泉旅行に行きたくてしかたがない。好きな食べものは、イチゴ。