GAEでSpringMVCを動かしてみる

GoogleAppEngineの勉強中です。
GAEでJavaを使って開発する場合、JSP,Servletが使えます。が、MVCモデルでアプリ作成しようとすると、何らかのFrameworkを使わないとダメっぽい。

というわけで、SpringMVCを試してみました。

————————————————————–
使っている環境
Java JDK1.6.0_35(64bit版)
Google App Engine SDK for Java 1.7.1

Eclipse IDE for Java EE Developers_ Juno (4.2)64Bit版
The Google Plugin for Eclipse, for Eclipse 3.8/4.2 (Juno)

Spring Framework 3.2.2.RELEASE
commons-logging-1.1.2


(1)はじめに
Javaのフレームワークというと、Struts、Springくらいしか聞いたことがなくって、たまたま目にしたPlayFrameworkというものが結構よさそうだと思ってた。ただPlayFrameworkは、まだ仕様がちょっと落ち着いてないみたい、う~ん。

で調べてみると、比較資料がありました。
Comparing JVM Web Frameworks – Devoxx France 2013

この資料は、すごい参考になったんだけど、スライド90枚に及ぶ長編スペクタクルなので、簡単にポイントを紹介します。

資料の40~44ページに、比較項目にポイント付けして、ランキングしたものがあります。
Grailsが1位になってるんですけど、どうなんでしょうか。Springは2位ですね。

57ページに、各種情報サイト?で紹介されているTop JVM Frameworkがのっています。選定基準は謎ですけど、有名どころ?と思われるFrameworkはこのあたりのものなんでしょうか。

69ページから、GoogleTrendでどんだけ話題になっているか、
73ページから、JobTrend(仕事で需要あるか)、
なんてことも紹介されています。

そして、最終的に筆者は、「俺に聞くな、自分で考えろ」と言っています(笑)。

Prioritize a list of goals that are important to your application.
・目的を一覧にして、優先順位をつける
Pick 3-4 frameworks and do a spike with each, developing the same application.
・3~4つのフレームワークをつかって、同じ機能のアプリ作成してみる。
Document and rank each framework against your list of goals.
・目的を一覧化し、それぞれの項目について各フレームワークに点数をつける
Calculate and choose!
・ランキングして、どれにするか選ぶ
Don’t be a Picker
・適当にチョイスするのは避ける


(2)SpringFrameworkのダウンロード
こちらのサイトの、一番下のところにProjectsという一覧があって、そこのSpring Frameworkのページに行きます。
SpringSource.org

spring_framework

そうすると、右のほうに、ダウンロード・ドキュメントへのリンクがあります。
僕の場合、spring-framework-3.2.2.RELEASE-dist.zip をダウンロードしました。


(3)Commons Loggingのダウンロード
Springを動かしてみるとわかるんですが、起動時にCommons LoggingがないとClass NotFoundエラーが出ます。
古いバージョンのSpringだと、SpringFrameworkのダウンロードすると、中にCommons Loggingのjarファイルも入ってたみたいですが、今は別になっているようです。

こちらのサイトの、Downloadから入手できます。
Commons Logging – Overview

僕の場合、commons-logging-1.1.2-bin.tar.gz をダウンロードしました。


(4)ライブラリ追加
とりあえず、超シンプルなアプリで試してみたいだけなので、必要最小限のjarファイルをライブラリに追加します。
追加するファイルはこちら7つ。

commons-logging-1.1.2.jar
spring-beans-3.2.2.RELEASE.jar
spring-context-3.2.2.RELEASE.jar
spring-core-3.2.2.RELEASE.jar
spring-expression-3.2.2.RELEASE.jar
spring-web-3.2.2.RELEASE.jar
spring-webmvc-3.2.2.RELEASE.jar

これらのjarファイルを、Eclipseの“war/WEB-INF/lib”フォルダに、配置します。
spring_library1

また、Eclipseの、「Java Build Path」に追加します。
spring_library2


(5)コーディング
こちらのサイトを参考にして、サンプル作成しました。
Google App Engine + Spring 3 MVC REST example
Getting Started With Spring MVC and Google App Engine | [Be el o ge]

まずは、Controllerを作成します。

Eclipseのsrcフォルダ配下に、パッケージsample.controllerを作成し、その中にMovieController.javaを作成します。
File名:src/sample/controller/MovieController.java

package sample.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/movie")
public class MovieController {

    //DI via Spring
    String message;

    @RequestMapping(value="/{name}", method = RequestMethod.GET)
    public String getMovie(@PathVariable String name, ModelMap model) {

        model.addAttribute("movie", name);
        model.addAttribute("message", this.message);

        //return to jsp page, configured in mvc-dispatcher-servlet.xml, view resolver
        return "list";

    }

    public void setMessage(String message) {
        this.message = message;
    }

}

次に、JSPファイルを作成します。
File名:war/pages/list.jsp

<html>
<body>
    <h1>GAE + Spring 3 MVC REST example</h1>

    <h3>Movie : ${movie} , DI message : ${message}</h3>    
</body>
</html>

次に、SpringのBean定義ファイルを作成します。
File名:war/WEB-INF/mvc-dispatcher-servlet.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.2.xsd
                        http://www.springframework.org/schema/mvc
                        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
                        ">

<!--
    <context:component-scan base-package="sample.controller">
        <context:exclude-filter type="regex"
            expression="sample.controller.Movie.*" />
    </context:component-scan>
-->

    <mvc:annotation-driven />

    <!-- Bean to show you Di in GAE, via Spring, also init the MovieController -->
    <bean class="sample.controller.MovieController">
        <property name="message">
            <value>Hello World</value>
        </property>
    </bean>

    <bean
       class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

</beans>

GoogleAppEngineでは、アプリ起動時にかかる時間を気にする必要があります。(今回はサンプルアプリなので気にしなくていいですが)

こちらの情報によると、
Optimizing Spring Framework for App Engine Applications – Google App Engine — Google

Springの「Component Scanning」は使わないほうがいいとのことです。
なので、context:component-scan タグを使わないようにしました。

ファイルの頭で、xmlの定義を読込ませているところ(以下の項目)
xmlns:context
xmlns:mvc
xsi:schemaLocation

は、漏れの無いように注意です。僕は「xmlns:mvc」を書き忘れていて、アプリ起動時にmvc-dispatcher-servlet.xmlの読込エラーが発生して悩まされました。

次に、web.xmlを修正します。
File名:war/WEB-INF/web.xml

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

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>
                    org.springframework.web.servlet.DispatcherServlet
                </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
                    org.springframework.web.context.ContextLoaderListener
                </listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>

作成したソースコードの配置場所をまとめると、こんな感じになります。

spring_files


(6)アプリ起動
ブラウザから、アクセスするとこんな感じ。
spring_sample_view

リクエストで、/movie/*** としたときの、***の部分が、
ブラウザ画面上で「Movie : ***」と表示されます。

上記の画面キャプチャは、自分のPC上(開発環境)のものですが、GAE上に実際にDeployしてもきちんと動きました。よかった。


4/21追記
テンプレートエンジンにApache Velocityを使ってみました。
GAEでSpringMVCを動かしてみる2(テンプレートエンジンVelocityを組込む) | Walk on apps.

Leave a comment