2.3. はじめてのSpring MVCアプリケーション¶
Caution
本バージョンの内容は既に古くなっています。最新のガイドラインはこちらからご参照ください。
Spring MVCの、詳細な使い方の解説に入る前に、実際にSpring MVCに触れることで、 Spring MVCを用いたWebアプリケーションの開発に対するイメージをつかむ。
本節は、全体イメージをつかむことを目的としており、 次章以降で説明する推奨方式に従っていないことに注意する。
2.3.1. 検証環境¶
本節の説明では、次の環境で動作検証している。(他の環境で実施する際は、本書をベースに適宜読み替えて設定していくこと。)
Product | Version |
---|---|
JDK | 1.6.0_33 |
SpringSource Tool Suite (STS) | 3.2.0 |
VMware vFabric tc Server Developer Edition | 2.8 |
Fire Fox | 21.0 |
Note
インターネット接続するために、プロキシサーバーを介する必要がある場合、 以下の作業を行うため、STSのProxy設定と、 MavenのProxy設定が必要である。
Warning
この節で使用するSpring Tool Suiteの「Spring Template Project」はSpiring Tool Suite 3.4から廃止されたため、この節の内容はSpiring Tool Suite 3.3以前でしか確認できない。
Spiring Tool Suite 3.4を使用する場合はBlankプロジェクトから新規プロジェクト作成を参照されたい。
今後、検証環境を更新する予定である。
2.3.2. 新規プロジェクト作成¶
SpringSource Tool Suiteのメニューから、[File] -> [New] -> [Spring Template Project] -> [Spring MVC Project] -> [Next]を選択し、 Spring MVCプロジェクトを作成する。
Note
Proxyサーバーを経由している場合、Spring Template Projectが選択できないことがある。 これを解決するには、以下のように、実施すること。
- まず、[window] -> [Preferences] -> [Spring] -> [Template Projects] を選択し、”spring-defaults”を残して、他項目をRemoveする。
- 次に、Preferences右下のApplyをクリックする。
- 最後に、[File] -> [New] -> [Spring Project]をクリックすると、Templetesから[Spring MVC Project]が、選択できるようになる。
次の画面で、[Project Name]に”helloworld”、[Please specify the top-level package]に”com.example.helloworld”を入力し、[Finish]をクリックする。
Package Explorerに、次のようなプロジェクトが生成される( 要インターネット接続 )。
Spring MVCの設定方法を理解するために、生成されたSpring MVCの設定ファイル(src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml)を、以下に転記し、簡単に説明する。
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->
<!-- (1) Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- (2) Resolves views selected for rendering by @Controllers to .jsp resources
in the /WEB-INF/views directory -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<!-- (3) -->
<context:component-scan base-package="com.example.helloworld" />
</beans:beans>
項番 | 説明 |
---|---|
(1)
|
<annotation-driven /> を定義することにより、Spring MVCのデフォルト設定が行われる。デフォルトの設定については、 Springの公式ページである Enabling the MVC Java Config or the MVC XML Namespace を参照されたい。 |
(2)
|
ViewのResolverを指定し、Viewの配置場所を定義する。 |
(3)
|
Spring MVCで使用するコンポーネントを探すパッケージを定義する。 |
com.example.helloworld.HomeController
を以下に示す(ただし、説明用に、シンプルな形に修正している)。
package com.example.helloworld;
import java.util.Date;
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;
/**
* Handles requests for the application home page.
*/
@Controller// (1)
public class HomeController {
private static final Logger logger = LoggerFactory
.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET) // (2)
public String home(Model model) { // (3)
logger.info("Welcome home!");
Date date = new Date();
model.addAttribute("serverTime", date);
return "home"; // (4)
}
}
簡単に、解説を行う。
項番 | 説明 |
---|---|
(1)
|
@Controller アノテーションを付けることで、DIコンテナにより、コントローラクラスが自動で読み込まれる。前述「Spring MVCの設定ファイルの説明(3)」の設定により、component-scanの対象となっている。 |
(2)
|
HTTPメソッドがGETで、Resource(もしくはRequest URL)が”/”で、アクセスする際に実行される。 |
(3)
|
Viewに渡したいオブジェクトを設定する。 |
(4)
|
View名を返却する。前述「Spring MVCの設定ファイルの説明(2)」の設定により、”WEB-INF/views/home.jsp”がレンダリングされる。 |
Modelに設定したオブジェクトが、HttpServletRequestに設定される。
home.jspで以下のように ${serverTime}
を記述することで、Controllerから渡された値を出力することができる。
( ただし、${XXX}の記述は、XSS対象になる可能性があるので、文字列を出力する場合は、後述のようにHTMLエスケープする必要があることに注意する。 )
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<P> The time on the server is ${serverTime}. </P>
</body>
</html>
2.3.3. サーバーを起動する¶
2.3.4. エコーアプリケーションの作成¶
続いて、簡単なアプリケーションを作成する。作成するのは、次の図のようなテキストフィールドに、名前を入力すると メッセージを表示する、いわゆるエコーアプリケーションである。
2.3.4.1. フォームオブジェクトの作成¶
com.example.helloworld.echo
パッケージにEchoForm
クラスを作成する。プロパティを1つだけ持つ、単純なJavaBeanである。package com.example.helloworld.echo;
import java.io.Serializable;
public class EchoForm implements Serializable {
private static final long serialVersionUID = 2557725707095364445L;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
2.3.4.2. Controllerの作成¶
com.example.helloworld.echo
パッケージに、EchoController
クラスを作成する。package com.example.helloworld.echo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("echo")
public class EchoController {
@ModelAttribute // (1)
public EchoForm setUpEchoForm() {
EchoForm form = new EchoForm();
return form;
}
@RequestMapping // (2)
public String index(Model model) {
return "echo/index"; // (4)
}
@RequestMapping("hello") // (5)
public String hello(EchoForm form, Model model) {// (3)
model.addAttribute("name", form.getName()); // (6)
return "echo/hello";
}
}
項番 | 説明 |
---|---|
(1)
|
@ModelAttribute というアノテーションを、メソッドに付加する。このアノテーションがついたメソッドの返り値は、自動でModelに追加される。Modelの属性名を、
@ModelAttribute で指定することもできるが、デフォルトでは、クラス名の先頭を小文字にした値が、属性名になる。この場合は、”echoForm”である。フォームの属性名は、次に説明する form:form タグ の modelAttribute 属性の値に一致している必要がある。 |
(2)
|
メソッドに付加した
@RequestMapping アノテーションの value 属性に、何も指定しない場合、クラスに付加した @RequestMapping のルートに、マッピングされる。この場合、”<contextPath>/echo”にアクセスすると、 index メソッドが呼ばれる。method 属性に何もしない場合は、任意のHTTPメソッドでマッピングされる。 |
(3)
|
引数に、EchoFormには(1)によりModelに追加されたEchoFormオブジェクトが渡される。
|
(4)
|
View名で”echo/index”を返すので、ViewResolverにより、 “WEB-INF/views/echo/index.jsp”がレンダリングされる。
|
(5)
|
メソッドに付加した
@RequestMapping アノテーションに”hello”を指定しているので、この場合、”<contextPath>/echo/hello”にアクセスすると hello メソッドが呼ばれる。 |
(6)
|
フォームで入力された
name を、Viewにそのまま渡す。 |
2.3.4.3. JSPの作成¶
最後に、入力画面と、出力画面のJSPを作成する。それぞれのファイルパスは、View名に合わせて、次のようになる。
- 入力画面 src/main/webapp/WEB-INF/views/echo/index.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html>
<html>
<head>
<title>Echo Application</title>
</head>
<body>
<!-- (1) -->
<form:form modelAttribute="echoForm" action="${pageContext.request.contextPath}/echo/hello">
<form:label path="name">Input Your Name:</form:label>
<form:input path="name" />
<input type="submit" />
</form:form>
</body>
</html>
項番 | 説明 |
---|---|
(1)
|
タグライブラリを利用し、HTMLフォームを構築している。
modelAttribute 属性に、Controllerで用意したフォームオブジェクトの名前を指定する。タグライブラリは こちらを参照されたい。
|
出力されるHTMLは、
<body>
<form id="echoForm" action="/helloworld/echo/hello" method="post">
<label for="name">Input Your Name:</label>
<input id="name" name="name" type="text" value=""/>
<input type="submit" />
</form>
</body>
</html>
となる。
- 出力画面 src/main/webapp/WEB-INF/views/echo/hello.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html>
<html>
<head>
<title>Echo Application</title>
</head>
<body>
<p>
Hello <c:out value="${name}" />!
</p>
</body>
</html>
Controllerから渡された”name”を出力する。 c:out
タグにより、XSS対策を行っている。
Note
ここではXSS対策を標準タグの c:out
で実現したが、より容易に使用できる f:h()
関数を共通ライブラリで用意している。
詳細は、 XSS対策 を参照されたい。
2.3.4.4. 入力チェックの実装¶
ここまでのアプリケーションでは、入力チェックを行っていない。 Spring MVCでは、Bean Validation (JSR-303)をサポートしており、アノテーションベースな入力チェックを、簡単に 実装することができる。例として、エコーアプリケーションで名前の入力チェックを行う。
Bean Validationを利用するために、pom.xmlのdependenciesの中に、以下のdependencyを追加する。
<!-- Bean Validation (JSR-303) -->
<dependency>
<artifactId>hibernate-validator</artifactId>
<groupId>org.hibernate</groupId>
<version>4.3.1.Final</version>
</dependency>
EchoForm
を以下の通り、 name
プロパティに @NotNull
アノテーションおよび、 @Size
アノテーションを付加する(getterメソッドに付加してもよい)。
package com.example.helloworld.echo;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class EchoForm implements Serializable {
private static final long serialVersionUID = 2557725707095364446L;
@NotNull // (1)
@Size(min = 1, max = 5) // (2)
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
項番 | 説明 |
---|---|
(1)
|
@NotNull アノテーションをつけることで、HTTPリクエスト中に name パラメータがあることを確認する。 |
(2)
|
@Size(min = 1, max = 5) をつけることで、name のサイズが、1以上5以下であることを確認する。 |
EchoController
を以下の通り、 @Valid
アノテーションを追加し、 hasErrors
メソッドを追加する。
package com.example.helloworld.echo;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("echo")
public class EchoController {
@ModelAttribute
public EchoForm setUpEchoForm() {
EchoForm form = new EchoForm();
return form;
}
@RequestMapping
public String index(Model model) {
return "echo/index";
}
@RequestMapping("hello")
public String hello(@Valid EchoForm form, BindingResult result, Model model) { // (1)
if (result.hasErrors()) { // (2)
return "echo/index";
}
model.addAttribute("name", form.getName());
return "echo/hello";
}
}
項番 | 説明 |
---|---|
(1)
|
コントローラー側には、Validation対象の引数に
@Valid アノテーションを付加し、 BindingResult オブジェクトを引数に追加する。Bean Validationによる入力チェックは、自動で行われる。結果は、
BindingResult オブジェクトに渡される。 |
(2)
|
hasErrors メソッドを実行して、エラーがあるかどうかを確認できる。 |
入力画面 src/main/webapp/WEB-INF/views/echo/index.jsp に、 form:errors
タグを追加する。
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html>
<html>
<head>
<title>Echo Application</title>
</head>
<body>
<form:form modelAttribute="echoForm" action="${action}">
<form:label path="name">Input Your Name:</form:label>
<form:input path="name" />
<form:errors path="name" cssStyle="color:red" /><!-- (1) -->
<input type="submit" />
</form:form>
</body>
</html>
項番 | 説明 |
---|---|
(1)
|
入力画面には、エラーがあった場合に、エラーメッセージを表示するため、
form:errors タグを追加する。 |
- 名前を空にして送信した場合
- 5文字より大きいサイズで送信した場合
出力されるHTMLは、
<body>
<form id="echoForm" action="/helloworld/echo/hello" method="post">
<label for="name">Input Your Name:</label>
<input id="name" name="name" type="text" value=""/>
<span id="name.errors" style="color:red">size must be between 1 and 5</span>
<input type="submit" />
</form>
</body>
</html>
となる。
2.3.4.5. まとめ¶
この章では、
- 最も簡易な、SpringMVCの設定ファイル設定方法
- 最も簡易な、画面遷移方法
- 画面間での値の引き渡し方法
- シンプルな入力チェック方法
を学んだ。
上記の内容が理解できていない場合は、もう一度、本節を読み、環境構築から始めて、進めていくことで理解が深まる。