Spring MVC チュートリアル

このSpring MVCのチュートリアルでは、Spring Tool Suiteを使用してSpring MVCウェブアプリケーションを開発する方法を学びます。Spring MVCフレームワークは、Javaのウェブアプリケーションで広く利用されています。

春のMVC

ストラットフレームワークと同様に、Spring MVCもJava EEのサーブレットとJSP技術に基づいており、モデル・ビュー・コントローラーの設計パターンを実装しています。

春のMVCチュートリアル

以前にSpringの依存性注入の仕組みを見たことがあり、このチュートリアルではSpring MVCフレームワークを使用してシンプルなウェブアプリケーションを作成する方法を学びます。Springプロジェクトの開発にはEclipseまたはIntelliJ IDEを使用することができますが、SpringSourceはEclipseベースの統合開発環境であるSpring Tool Suite(STS)を提供しており、その中にはApache TomcatコンテナをベースにしたVMware vFabric tc Serverが組み込まれており、Springベースのアプリケーションに最適化されています。Spring MVCチュートリアルや他の将来のチュートリアルでは、STSを使用します。なぜなら、開発者の生活を簡単にしてくれる以下の機能を提供しているからです。

  • Support for creating skeletal Spring applications (MVC, Rest, Batch etc), good for starting the project from scratch. We will soon see in this spring MVC tutorial how easy it is to create a Spring MVC project.
  • Provides useful features such as creating Spring Configuration files, parsing config files and classes to provide useful information about them.
  • Automatic validation of Spring application
  • Refactoring support to easily make project changes, the changes get reflected in config files too.
  • Code assist for not only classes but configuration files too, I like this feature a lot because most of the times we need to know what we can use and its details.
  • Best support for Aspect Oriented Programming (AOP) through the integration of AspectJ.

STSの提供するすべての機能を見ると、私はそれに惹かれ、Springアプリケーションで使用することを決めました。そして今まで非常に満足しています。STS公式ダウンロードページからSTSをダウンロードし、インストールしてください。私はEclipse 4.3.1リリースに基づいているSTS 3.4.0.RELEASEを使用しています。もしSTSを使いたくない、既存のEclipseでその機能を使いたい場合は、Eclipse Marketplaceからプラグインをインストールする必要があります。以下の画像を参考にして、インストールのために正しいSTSのバージョンを選択してください。以下のプラグインはEclipse Kepler向けです。もしSpringSourceサーバーを使いたくない場合は、TomcatやJBossなどの他のJava EEコンテナにアプリケーションをデプロイすることもできます。このチュートリアルでは、STSに付属しているサーバーを使いますが、WARファイルとしてエクスポートして別のTomcatサーバーでテストしたらうまく動作しました。さて、サーバー環境とIDEの準備が整ったので、さあ、最初のSpring MVCプロジェクトを作成しましょう。以下の手順は、STSおよびSTSプラグインを持つEclipseの両方に有効です。

STSまたはEclipseでSpring MVCアプリケーションを作成する。

ステップ1:メニューから新しいSpringプロジェクトを作成します。ステップ2:新しいプロジェクトウィンドウで、「SpringMVCExample」という名前を付けて、「Spring MVCプロジェクト」としてテンプレートを選択します。このテンプレートを初めて使用する場合は、STSがSpringSourceのウェブサイトからダウンロードします。任意でプロジェクトを任意の作業セットに追加することもできます。ステップ3:テンプレートがダウンロードされると、次の画面で最上位のパッケージ名を指定する必要があります。このパッケージはSpringコンポーネントのベースパッケージとして使用されます。ステップ4:Spring MVCテンプレートによってプロジェクトが作成されたら、以下の画像のようになります。User.javaクラスやlogin.jsp、user.jspファイルが表示されなくても心配しないでください。それらは後から私が追加しました。プロジェクトがコンパイルされていない場合やエラーが表示される場合は、Maven/Update Projectを実行してください。以下の画像を参照し、「Snapshots/Releasesの強制更新」オプションをチェックしてください。全体的に見ると、プロジェクトは他のMavenベースのウェブアプリケーションと同じように見えます。これからプロジェクトの異なる部分を分析し、少し拡張していきましょう。

Spring MVCの依存関係

私たちの生成されたpom.xmlファイルは以下のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.scdev</groupId>
	<artifactId>SpringMVCExample</artifactId>
	<name>SpringMVCExample</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	<properties>
		<java-version>1.6</java-version>
		<org.springframework-version>4.0.0.RELEASE</org.springframework-version>
		<org.aspectj-version>1.7.4</org.aspectj-version>
		<org.slf4j-version>1.7.5</org.slf4j-version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
			<exclusions>
				<!-- Exclude Commons Logging in favor of SLF4j -->
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				 </exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
				
		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>	
		
		<!-- Logging -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${org.slf4j-version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.15</version>
			<exclusions>
				<exclusion>
					<groupId>javax.mail</groupId>
					<artifactId>mail</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.jms</groupId>
					<artifactId>jms</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jdmk</groupId>
					<artifactId>jmxtools</artifactId>
				</exclusion>
				<exclusion>
					<groupId>com.sun.jmx</groupId>
					<artifactId>jmxri</artifactId>
				</exclusion>
			</exclusions>
			<scope>runtime</scope>
		</dependency>

		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
				
		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
	
		<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>        
	</dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

ウェブアプリケーション用のartifactIdはservlet-contextになりますので、他のものに変更しても構いません。Spring Framework、AspectJ、SLF4jのバージョンにはいくつかのプロパティが定義されていますが、最新のバージョンとは異なることがわかりましたので、本日の最新安定版に変更しました。私が関心を持っているプロジェクト依存関係は次のとおりです。

  • spring-context: Spring Core dependency. Notice the exclusion of commons logging in favor of SLF4J.
  • spring-webmvc: Spring artifact for MVC support
  • aspectjrt: AspectJ API reference
  • SLF4J and Log4j: For logging purposes, Spring is very easy to configure for log4j or Java Logging API because of SLF4J integration.
  • javax.inject – JSR330 API for dependency injection

スターターアプリケーションでは、Servlet、JSP、JSTL、JUnit APIなどの他の依存関係が追加されていますが、それらは見逃すことができます。

Spring MVC チュートリアル – Log4j 設定

生成されたlog4j.xmlファイルは以下のように見えます。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="https://jakarta.apache.org/log4j/">

	<!-- Appenders -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p: %c - %m%n" />
		</layout>
	</appender>
	
	<!-- Application Loggers -->
	<logger name="com.scdev.spring">
		<level value="info" />
	</logger>
	
	<!-- 3rdparty Loggers -->
	<logger name="org.springframework.core">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.beans">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.context">
		<level value="info" />
	</logger>

	<logger name="org.springframework.web">
		<level value="info" />
	</logger>

	<!-- Root Logger -->
	<root>
		<priority value="warn" />
		<appender-ref ref="console" />
	</root>
	
</log4j:configuration>

コンソールにすべての内容が出力されていることに注意し、簡単にアペンダを追加してログをファイルにリダイレクトできます。

【日本語】
「Spring MVCチュートリアル – デプロイメントディスクリプタの設定」

私たちのweb.xmlを見て、分析しましょう。 (Watashitachi no web.xml wo mite, bunseki shimashou.)

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

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

ContextLoaderListenerはApplicationContextのライフサイクルをServletContextのライフサイクルに結びつけ、ApplicationContextの自動作成を行います。ApplicationContextはSpringのビーンの場所であり、contextConfigLocationのコンテキストパラメータを通じてその設定を提供することができます。root-context.xmlファイルはWebApplicationContextの設定詳細を提供します。DispatcherServletはSpring MVCアプリケーションのコントローラクラスであり、すべてのクライアントリクエストはこのサーブレットによって処理されます。設定はservlet-context.xmlファイルからロードされています。

Spring MVC チュートリアル – 設定ファイル

ルートコンテキスト.xmlファイル

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
		
</beans>

今のところ、ここで共有されるビーンを定義することができます。servlet-context.xmlのコードはまだ何もありません。

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="https://www.springframework.org/schema/beans"
	xmlns:context="https://www.springframework.org/schema/context"
	xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- 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/" />

	<!-- 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>
	
	<context:component-scan base-package="com.scdev.spring" />	
	
</beans:beans>

これが標準のSpring設定ファイルの表示方法です。自分でこれを書くことを想像してみてください。そうすれば、STSツールが好きになるでしょう。annotation-driven要素は、Controllerサーブレットにアノテーションが使用されることを知らせるために使用されます。resources要素は、Springフレームワークを介さずに取得したくない静的ファイル(画像、HTMLページなど)を配置する場所を定義します。InternalResourceViewResolverはビューリゾルバであり、prefixおよびsuffixプロパティを介してビューページの場所を指定できます。したがって、すべてのJSPページは/WEB-INF/views/ディレクトリに配置する必要があります。context:component-scan要素は、Controllerクラスをスキャンするための基本パッケージの場所を提供するために使用されます。プロジェクト作成時に指定されたトップレベルパッケージの値を覚えておいてください。ここでも同じ値が使用されています。

スプリングMVCコントローラークラス

ホームコントローラーは、home()メソッドとともに自動的に作成されますが、私はloginPage()メソッドとlogin()メソッドを追加して少し拡張しました。

package com.scdev.spring;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
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)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String loginPage(Locale locale, Model model) {
		return "login";
	}
	
	@RequestMapping(value = "/home", method = RequestMethod.POST)
	public String login(@Validated User user, Model model) {
		model.addAttribute("userName", user.getUserName());
		return "user";
	}
}

@Controllerアノテーションは、Webコントローラークラスであることを示すために使用されます。@RequestMappingは、クラスとメソッドと共に使用され、クライアントのリクエストを特定のハンドラーメソッドにリダイレクトします。ハンドラーメソッドはStringを返すことに注意してください。これは、レスポンスとして使用されるビューページの名前である必要があります。異なる文字列を返す3つのメソッドがあるため、同じ名前のJSPページを作成する必要があります。login()メソッドはHTTPメソッドとしてPOSTで呼び出されるため、ここではフォームデータが期待されます。したがって、Userモデルクラスを使用し、@Validatedアノテーションで検証されるようにマークされています。すべてのメソッドにはModelが引数として含まれており、JSPレスポンスページで後で使用する属性を設定することができます。

Spring MVCのモデルクラス

モデルクラスは、フォームの変数を保持するために使用されます。私たちのユーザーモデルビーンは、以下のようになります。

package com.scdev.spring;

public class User {

	private String userName;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
	
}

変数名とそのゲッターメソッドとセッターメソッドを持つシンプルなJavaのBean。

Spring MVC チュートリアル – ビューページ

以下のようなJSPページが3つあります。home.jspのコード:

<%@ taglib uri="https://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>

JSPの式言語を使用して属性値を取得している点に注意してください。login.jspのコードを確認してください。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login Page</title>
</head>
<body>
<form action="home" method="post">
<input type="text" name="userName"><br>
<input type="submit" value="Login">
</form>
</body>
</html>

ユーザがuserNameを入力するためのシンプルなJSPページです。フォームの変数名はUserクラスの変数名と同じです。また、フォームのアクションは「home」であり、メソッドは「post」です。明らかに、このリクエストはHomeControllerのlogin()メソッドで処理されます。user.jspのコードです。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>User Home Page</title>
</head>
<body>
<h3>Hi ${userName}</h3>
</body>
</html>

ログインメソッドでこの属性を設定していることに気づく、ユーザーのためのシンプルなホームページでユーザ名が表示されます。

Spring MVCのサンプルアプリケーションのテスト

私たちのアプリケーションは実行の準備ができていますので、VMware tc Serverまたは他のサーブレットコンテナーで実行してください。その結果として、以下のページが表示されます。これがSpring MVCのチュートリアルの全てです。STプラグインを使用してSpring MVCアプリケーションを簡単に作成する方法が分かります。コードサイズも非常に小さく、ほとんどの設定はSpring MVCが処理してくれるため、ビジネスロジックに集中できます。以下のリンクから例となるSpring MVCプロジェクトをダウンロードして、自由に操作してみてください。

Spring MVCプロジェクトをダウンロードする。

コメントを残す 0

Your email address will not be published. Required fields are marked *