LoginSignup
35
47

More than 5 years have passed since last update.

Spring5 MVC ~サンプルアプリ実装~

Last updated at Posted at 2018-03-26

Spring MVCを用いたWebアプリケーションの開発に対するイメージをつかむ為、画面遷移と入力チェックを行う簡単なサンプルアプリの実装解説を行います。

1. 検証環境

種別 プロダクト
JVM Java 1.8
Spring Framework Spring Framework 5.0.4 ※2018.3.26時点の最新バージョン
OS Windows 10
IDE eclipse4.7(oxygen) ※Pleiades All in One 4.7.2にSpring Tool Suite(STS)3.9.2をインストールして使用
Build Tool Maven 4.0.0
Application Server Tomcat 9.0.2
Web Browser GoogleChrome 65.0.3325.181

※Spring Frameworkの採用バージョンについて
Spring5系の対応JDKバージョンがJDK8で、それ以前のバージョンは未対応となっている事から、JDK8環境では、必然的に5系の採用となる。なお、Spring4系の最終バージョン4.3(2016/6/10リリース)については、Spring公式ブログにて、2019年までメンテナンスが続けられる予定とアナウンスされています。
(https://spring.io/blog/2016/06/10/spring-framework-4-3-goes-ga)

2. 新規プロジェクト作成

SpringSource Tool Suiteのメニューから、[ファイル] -> [新規] -> [Spring レガシー・プロジェクト] を選択する。

現れたダイアログで、以下のとおり入力し完了ボタンを押下します。

項目名 設定値
プロジェクト名 任意(ここでは HelloSpringMVC を入力)
デフォルトロケーションを使用 チェックあり
Springバージョンの選択 「Default」のまま
テンプレート 「Simple Spring Web Maven」を選択
ワーキングセットにプロジェクトを追加 チェックなし

プロジェクト作成後、作成したプロジェクトを右クリックし、[Maven] -> [プロジェクトの更新]を選択する。

現れたダイアログで、アップデート対象のプロジェクトのチェックがONになっている事を確認し、[OK]ボタンを押下し、プロジェクトのアップデートを行う。
※アップデートにより、pom.xmlに記載されたライブラリなどのダウンロードが行われるので、設定変更などの都度、この操作を行ってください。

プロジェクトを作成すると、下記構成のMavenベースのSpringMVCアプリが作成されます。

続いて、プロジェクトに適用される各種設定を適正値に変更します。
上の画像では、「JRE システム・ライブラリー[J2SE-1.5]」と表示されています。
JDK1.8を使用したいので、「JRE システム・ライブラリー[J2SE-1.5]」を右クリックし、[プロパティー]を選択し、現れたダイアログでJDK1.8を選択して[適用して閉じる]を押下してください。

この状態で、以下のとおり「問題」コンソールに下記のエラーが表示されます。

上記エラーが表示される場合は、プロジェクトを右クリックし、[プロパティー]を選択し、現れたダイアログで「プロジェクト・ファセット」を選択します。
プロジェクトで使用するファセットを下記表のとおり選択して、[適用して閉じる]を押下してください。

項目名 設定値
Java 1.8
JavaScript 1.0
動的 Web モジュール 3.1

3. サーバーを実行する

下記のとおり、プロジェクトを右クリックし、[実行] -> [1 サーバーで実行]を選択し、

現れたダイアログで任意のサーバ(ここではTomcat9)を選択し、[完了]ボタンを押下する。

下記のとおり、Tomcatが正常起動し、「http://localhost:8080/HelloSpringMVC/」で「Click to enter」と表示の画面が表示されればセットアップ完了です。

4. pom.xmlを変更する。

「1.検証環境」に記載のJDK、SpringFrameworkのバージョンなどに合わせる為、HelloSpringMVC/pom.xmlを以下のとおり修正してください。

pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.samples.service.service</groupId>
  <artifactId>HelloSpringMVC</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

    <build>
      <plugins>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
         </plugin>
       </plugins>
    </build>

    <properties>

        <!-- Generic properties -->
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Web -->
        <jsp.version>2.2</jsp.version>
        <jstl.version>1.2</jstl.version>
        <servlet.version>3.1.0</servlet.version>

        <!-- Spring -->
        <spring-framework.version>5.0.4.RELEASE</spring-framework.version>

        <!-- Spring Data JPA -->
        <spring-data-jpa.version>2.0.0.RELEASE</spring-data-jpa.version>

        <!-- Hibernate / JPA -->
        <hibernate.version>5.2.10.Final</hibernate.version>

        <!-- Hibernate validator -->
        <hibernate-validator.version>6.0.2.Final</hibernate-validator.version>

        <!-- H2 database -->
        <h2.version>1.4.196</h2.version>

        <!-- Logging -->
        <logback.version>1.2.3</logback.version>
        <slf4j.version>1.7.25</slf4j.version>

        <!-- Test -->
        <junit.version>4.12</junit.version>

    </properties>

    <dependencies>

        <!-- Spring MVC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!-- Other Web dependencies -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${servlet.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>${jsp.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- Spring and Transactions -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!-- Logging with SLF4J & LogBack -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
            <scope>runtime</scope>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <!-- jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!--  Spring Data JPA -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring-data-jpa.version}</version>
        </dependency>

        <!-- Spring ORM -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!-- h2 database -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${h2.version}</version>
        </dependency>

        <!-- Hibernate validator -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>${hibernate-validator.version}</version>
        </dependency>

        <!-- Test Artifacts -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring-framework.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>

pom.xmlの変更により以下のエラーが出力された場合は、

web.xmlのヘッダー部分の宣言バージョンを以下のとおり修正してください。

(変更前)web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         id="WebApp_ID" version="2.5">
(変更後)web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
 version="3.1">

修正後、プロジェクトを右クリック、[Maven] -> [プロジェクトの更新]を選択して、修正を反映してください。

5. web.xmlを変更する。

Spring MVCがリクエストを処理するため、以下のとおり、src/main/webapp/WEB-INF/web.xmlを修正してください。

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
 version="3.1">

    <display-name>SpringMvcTest</display-name>

    <!-- Spring設定ファイルの配置パスの定義 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/application-config.xml</param-value>
    </context-param>

    <!-- 上記のSpring設定ファイルを読み込むリスナの定義 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- spring mvcがリクエストを処理するサーブレットの定義 -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/mvc-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- 上記サーブレットのURLマッピング定義 -->
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

6. mvc-config.xmlを変更する。

web.xmlに定義したorg.springframework.web.servlet.DispatcherServletが読み込むSpring MVCの設定ファイルsrc/main/webapp/WEB-INF/mvc-config.xmlを以下のとおり修正してください。

mvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- Spring MVCのデフォルト設定を定義 -->
    <mvc:annotation-driven />

    <!-- Spring MVCで使用するコンポーネントのルートパッケージを定義 -->
    <context:component-scan base-package="hello.spring.mvc.echo"/>

    <!-- Spring MVCで使用するJSPファイルの配置場所を定義 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/view/"/>
            <property name="suffix" value=".jsp"/>
    </bean>

</beans>

7. エコーアプリケーションの作成

続いて、実際に簡単なアプリケーションを作成します。作成するのは、以下の画面のようにテキストフィールドに名前を入力して送信ボタンを押下するとメッセージ表示画面へ遷移する、いわゆるエコーアプリケーションです。
また、作成するエコーアプリケーションでは、以下の入力チェックを行い、入力エラーの場合は、エラーメッセージを表示するものとします。
 ・名前を空にして送信した場合
 ・5文字より大きいサイズで送信した場合

●初期表示画面(input.jsp)

●入力された名前を表示する画面(echo.jsp)

●入力チェックエラー時はメッセージを表示する。

  1. フォームオブジェクトの作成

入力画面で入力値を受け取るための、フォームオブジェクトを作成します。
hello.spring.mvc.echoパッケージにEchoFormクラスを作成します。プロパティを1つだけ持つ、単純なJavaBean(POJO)です。
※StrutsだとActionFormに位置するクラスになります。

EchoForm.java
package hello.spring.mvc.echo;

import java.io.Serializable;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

public class EchoForm implements Serializable {

    @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以下であることを確認する入力チェックが可能となります。

2. Controllerの作成
次に、Controllerを作成します。
同じくhello.spring.mvc.echoパッケージに、EchoControllerクラスを作成します。
※Strutsだと、Actionクラスに位置するものになります。

EchoController.java
package hello.spring.mvc.echo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller // (1)
public class EchoController {

    @ModelAttribute // (2)
    public EchoForm setUpEchoForm() {
        EchoForm form = new EchoForm();
        return form;
    }

    @RequestMapping // (3)
    public String index(Model model) {
        return "echo/input"; // (4)
    }

    @RequestMapping(value = "echo/echo", method = RequestMethod.POST) // (5)
    public String echo(@Validated EchoForm form, BindingResult result, Model model) { // (6)

        if (result.hasErrors()) { // (7)
            return "echo/input";
        }

        model.addAttribute("name", form.getName()); // (8)
        return "echo/echo";
    }

}

項番 説明
(1)  @Controllerアノテーションの付与により、このクラスがControllerクラスである事をSpringが認識し使用可能となります。
(2)  @ModelAttributeアノテーションを付与したメソッドの戻り値が自動でModel(ここではクライアントからのHTTPリクエストと、それを受け取るフォームオブジェクトの紐付け)に追加される。Modelの属性名を、 @ModelAttribute で指定することもできるが、デフォルトでは、クラス名の先頭を小文字にした値が、属性名になる。この場合は、”echoForm”となります。フォームの属性名は、次に説明する form:form タグ の modelAttribute 属性の値に一致している必要がある。※Strutsの場合、Actionクラスが使用するActionFormはstruts-config.xmlで紐付けを行うが、Springは、アノテーションで指定します。
(3)  メソッドに付加した @RequestMapping アノテーションの value 属性に指定したルートに、マッピングされる。この場合、”/echo”にアクセスすると、 index メソッドが呼ばれる。method 属性に何もしない場合は、任意のHTTPメソッドでマッピングされます。
(4)  View名で”echo/input”の文字列を返すと、ViewResolverにより、 “WEB-INF/view/echo/input.jsp”がレンダリングされます。
(5)  メソッドに付加した @RequestMapping アノテーションのvalue属性に”echo/echo”を、method属性にRequestMethod.POSTを指定しているので、この場合、”/echo/echo”にPOSTメソッドを使用してアクセスすると echoメソッドが呼ばれます。
(6)  引数のEchoFormには(2)によりModelに追加されたEchoFormオブジェクトが渡される。EchoFormのnameパラメータの入力チェックを行う為、@Validated アノテーションを付加し、 BindingResult オブジェクトを引数に追加する。Bean Validationによる入力チェックは、自動で行われる。結果は、 BindingResult オブジェクトに渡されます。
(7)  hasErrors メソッドを実行して、エラーがあるかどうかを確認します。入力エラーがある場合は、入力画面を表示するためのView名を返却します。
(8)  フォームで入力された name を、Viewにそのまま渡します。

3. JSPの作成
最後に、入力画面と、出力画面のJSPを作成します。それぞれのファイルパスは、View名に合わせて、次のようにします。
先ず、入力画面 (src/main/webapp/WEB-INF/view/echo/input.jsp) を作成します。

input.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/echo">
    <form:label path="name">Input Your Name:</form:label>
    <form:input path="name" />
    <form:errors path="name" cssStyle="color:red" /><%-- (2) --%>
    <br>
    <input type="submit" />
  </form:form>
</body>
</html>
項番 説明
(1)  Springのタグライブラリを利用し、HTMLフォームを構築します。 modelAttribute 属性に、Controllerで用意したフォームオブジェクトの名前を指定します。
(2)  入力チェックでエラーがあった場合に、エラーメッセージを表示するため、 form:errors タグを追加します。

※SpringもStrutsと同様にJSP向けのタグライブラリが用意されています。
Spring’s JSP tag library

出力されるHTMLは、以下のとおりとなります。

input.jspから出力されるHTML
<!DOCTYPE html>
<html>
<head>
<title>Echo Application</title>
</head>
<body>

  <form id="echoForm" action="/HelloSpringMVC/echo/echo" method="post">
    <label for="name">Input Your Name:</label>
    <input id="name" name="name" type="text" value=""/>

    <br>
    <input type="submit" />
  </form>
</body>
</html>

出力画面 (src/main/webapp/WEB-INF/view/echo/echo.jsp) を作成します。

echo.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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Echo Application</title>
</head>
<body>
  <p>
    Hello <c:out value="${name}" /> <%-- (1) --%>
  </p>
</body>
</html>
項番 説明
(1)  Controllerから渡された”name”を出力する。 c:outタグにより、XSS対策(特殊文字(<,>,&,',")のエスケープ出力)を行います。

これでエコーアプリケーションの実装は完了です。
サーバーを起動し、http://localhost:8080/HelloSpringMVC/echoにアクセスすると画面が表示されます。

以上で、Spring MVCの基本的な実装イメージがつかめたかと思います。

他にも
独自の入力チェックの実装方法は?
例外ハンドリングは?
セッション管理は?
メッセージ管理は?など
色々気になるところがあるかと思いますが、基本的にアノテーションベースな実装で簡易に出来るようです。

[Spring Web MVC]
https://docs.spring.io/spring/docs/5.0.4.RELEASE/spring-framework-reference/web.html#mvc

[本ページ作成にあたり、参考にさせてもらったサイト]
http://terasolunaorg.github.io/guideline/5.4.1.RELEASE/ja/index.html

ありがとうございました。

35
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
47