JSONIC + Slim3 + GAE/JでRESTサービスを構築する方法 Part2

前回の記事はこちら

今回は、Eclipse用のMavenプロジェクトを作成して、JSONIC + Slim3 + GAE/Jを使えるように設定する方法を紹介。

最初に、MavenEclipseプラグインをいれておきましょう。下記の記事が参考になるかと。

このプラグインがないと、話が進みません・・・。

さて、EclipseMavenプラグインをインストールして準備が整ったところで、Mavenプロジェクトを作成していきます。まずは、下の手順に従ってコマンドを実行していき、Eclipse用のMavenプロジェクトを作ります([Enter]はデフォルトのままEnterキーを押すことを表す)。なお、自分の環境がMacOSXなので、Shellで話を進めます。ごめんなさい。Windowsの方は、How to install Maven on Windowsとか参考に、mvnコマンドが使えるようにしていただければいいかと。

$ mvn archetype:generate
中略
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 164: 167
(「164」や「167」は環境により変化する。「maven-archetype-webapp」を選ぶこと)
Choose a number: 5: [Enter]
Define value for property 'groupId': : com.example
Define value for property 'artifactId': : restapp
Define value for property 'version':  1.0-SNAPSHOT: : [Enter]
Define value for property 'package':  com.example: : [Enter]
Y: : [Enter]

ここまでで、Mavenプロジェクト自体は完成。下記のコマンドを実行して、Eclipse用のMavenプロジェクトに変換します。

$ cd restapp
$ mvn eclipse:eclipse

次に、作成したプロジェクトをEclipseにインポートします。[File]>[Import...]を実行してImportダイアログを開いてください。続いて、[Maven]>[Existing Maven Projects]を選択して次へ進みます。

Root Directoryにrestappのフルパスを指定してインポートを完了させます(下の画像参照)。

あとはEclipse上で作業。まずは、足りないフォルダを作ってソースフォルダに指定しましょう。
作るのは、src/main/javaとsrc/test/javaとsrc/test/resources。作ったあとは、ビルドバスの設定でソースフォルダに指定。下の画像と同じようになっていれば良いかと。

次は、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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>restapp</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>restapp Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <repositories>
  	<repository>
  		<releases>
  			<updatePolicy>never</updatePolicy>
  		</releases>
  		<id>maven.seasar.org</id>
  		<name>The Seasar Foundation Maven2 Repository</name>
  		<url>https://www.seasar.org/maven/maven2</url>
  	</repository>
  	<repository>
  		<releases>
  			<updatePolicy>never</updatePolicy>
  		</releases>
  		<id>maven-gae-plugin-repo</id>
  		<name>maven-gae-plugin repository</name>
  		<url>http://maven-gae-plugin.googlecode.com/svn/repository</url>
  	</repository>
  	<repository>
  		<releases>
  			<updatePolicy>never</updatePolicy>
  		</releases>
  		<id>oss.sonatype.org</id>
  		<url>http://oss.sonatype.org/content/groups/jetty/</url>
  	</repository>
  	<repository>
  		<releases>
  			<updatePolicy>never</updatePolicy>
  		</releases>
  		<id>maven-res</id>
  		<url>http://maven.restlet.org</url>
  	</repository>
  </repositories>
  <pluginRepositories>
  	<pluginRepository>
  		<releases>
  			<updatePolicy>never</updatePolicy>
  		</releases>
  		<id>maven.seasar.org</id>
  		<name>The Seasar Foundation Maven2 Repository</name>
  		<url>https://www.seasar.org/maven/maven2</url>
  	</pluginRepository>
  	<pluginRepository>
  		<releases>
  			<updatePolicy>never</updatePolicy>
  		</releases>
  		<id>maven-gae-plugin-repo</id>
  		<name>maven-gae-plugin repository</name>
  		<url>http://maven-gae-plugin.googlecode.com/svn/repository</url>
  	</pluginRepository>
  </pluginRepositories>
  <dependencies>
  	<dependency>
  		<groupId>com.google.appengine</groupId>
  		<artifactId>appengine-api-1.0-sdk</artifactId>
  		<version>${gae.version}</version>
  		<type>jar</type>
  		<scope>compile</scope>
  	</dependency>
  	<dependency>
  		<groupId>com.google.appengine</groupId>
  		<artifactId>appengine-api-labs</artifactId>
  		<version>${gae.version}</version>
  		<type>jar</type>
  		<scope>test</scope>
  	</dependency>
  	<dependency>
  		<groupId>com.google.appengine</groupId>
  		<artifactId>appengine-api-stubs</artifactId>
  		<version>${gae.version}</version>
  		<type>jar</type>
  		<scope>test</scope>
  	</dependency>
  	<dependency>
  		<groupId>com.google.appengine</groupId>
  		<artifactId>appengine-testing</artifactId>
  		<version>${gae.version}</version>
  		<type>jar</type>
  		<scope>test</scope>
  	</dependency>
  	<dependency>
  		<groupId>org.slf4j</groupId>
  		<artifactId>slf4j-jdk14</artifactId>
  		<version>1.6.4</version>
  		<type>jar</type>
  		<scope>compile</scope>
  	</dependency>
  	<dependency>
  		<groupId>junit</groupId>
  		<artifactId>junit</artifactId>
  		<version>4.10</version>
  		<type>jar</type>
  		<scope>test</scope>
  	</dependency>
  	<dependency>
  		<groupId>org.slim3</groupId>
  		<artifactId>slim3</artifactId>
  		<version>${slim3.version}</version>
  		<type>jar</type>
  		<scope>compile</scope>
  		<exclusions>
  			<exclusion>
  				<artifactId>appengine-api-1.0-sdk</artifactId>
  				<groupId>com.google.appengine</groupId>
  			</exclusion>
  			<exclusion>
  				<artifactId>appengine-api-labs</artifactId>
  				<groupId>com.google.appengine</groupId>
  			</exclusion>
  		</exclusions>
  	</dependency>
  	<dependency>
  		<groupId>org.slim3</groupId>
  		<artifactId>slim3-gen</artifactId>
  		<version>${slim3.version}</version>
  		<type>jar</type>
  		<scope>provided</scope>
  		<exclusions>
  			<exclusion>
  				<artifactId>ant</artifactId>
  				<groupId>org.apache.ant</groupId>
  			</exclusion>
  		</exclusions>
  	</dependency>
  	<dependency>
  		<groupId>net.arnx</groupId>
  		<artifactId>jsonic</artifactId>
  		<version>1.2.7</version>
  		<type>jar</type>
  		<scope>compile</scope>
  	</dependency>
  	<dependency>
  		<groupId>javax.servlet</groupId>
  		<artifactId>servlet-api</artifactId>
  		<version>2.5</version>
  		<type>jar</type>
  		<scope>compile</scope>
  	</dependency>
  	<dependency>
  		<groupId>org.eclipse.jetty</groupId>
  		<artifactId>jetty-servlet-tester</artifactId>
  		<version>7.0.0.M2</version>
  		<type>jar</type>
  		<scope>compile</scope>
  	</dependency>
  </dependencies>
  <build>
    <finalName>restapp</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <encoding>utf-8</encoding>
                <source>1.6</source>
                <target>1.6</target>
                <optimize>true</optimize>
                <debug>true</debug>
            </configuration>
        </plugin>
        <plugin>
            <groupId>net.kindleit</groupId>
            <artifactId>maven-gae-plugin</artifactId>
            <version>0.9.2</version>
            <configuration>
                <sdkDir>${appengine.sdk.dir}</sdkDir>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <webResources>
                    <resource>
                        <directory>src/main/webapp</directory>
                        <filtering>true</filtering>
                        <includes>
                            <include>**/appengine-web.xml</include>
                        </includes>
                    </resource>
                </webResources>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>add-source</goal>
                    </goals>
                    <configuration>
                        <sources>
                            <source>${generated.src}</source>
                        </sources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>apt-maven-plugin</artifactId>
            <configuration>
                <encoding>utf-8</encoding>
                <outputDirectory>${generated.src}</outputDirectory>
                <options>
                    <option>slim3.rootPackage=com.example</option>
                </options>
            </configuration>
            <executions>
                <execution>
                    <phase>process-sources</phase>
                    <goals>
                        <goal>process</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-clean-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <filesets>
                    <fileset>
                        <directory>build</directory>
                    </fileset>
                </filesets>
            </configuration>
        </plugin>
    </plugins>
    <pluginManagement>
    	<plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>1.7</version>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.0-alpha-4</version>
                <dependencies>
                    <dependency>
                        <groupId>org.slim3</groupId>
                        <artifactId>slim3-gen</artifactId>
                        <version>${slim3.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </pluginManagement>
  </build>
  <properties>
    <slim3.version>1.0.14</slim3.version>
    <generated.src>target/apt_generated</generated.src>
    <generated.war>war</generated.war>
    <gae.version>1.6.0</gae.version>
    <appengine.sdk.dir>/appengine-java-sdk-1.6.0</appengine.sdk.dir>
  </properties>
</project>

最後は、web.xmlの修正とappengine-web.xmlの作成。
web.xmlは、下記の通りに修正してください。

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

    <filter-mapping>
        <filter-name>DatastoreFilter</filter-name>
        <url-pattern>/restapp/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

    <servlet>
        <servlet-name>restServlet</servlet-name>
        <servlet-class>net.arnx.jsonic.web.RESTServlet</servlet-class>
        <init-param>
            <param-name>config</param-name>
            <param-value>
                {
                    "debug": true,
                    "mappings": {
                        "/restapp/{class}.json":"com.example.controller.${class}Controller"
                    }
                }
            </param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>restServlet</servlet-name>
        <url-pattern>*.json</url-pattern>
    </servlet-mapping>
</web-app>

appengine-web.xmlは、src/main/webapp/WEB-INFの下に作成して、下記の内容を記述してください。

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <application>restapp</application>
    <version>1</version>

    <static-files>
        <include path="/**.*"/>
    </static-files>

    <system-properties>
        <property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties"/>
	<property name="file.encoding" value="UTF-8"/>
        <property name="DEFAULT_ENCODING" value="UTF-8"/>
	<!-- key length should be 16 -->
	<property name="slim3.cipherGlobalKey" value="1234567890"/>
    </system-properties>
</appengine-web-app>

slim3.cipherGlobalKey」のvalueは適当な値で。これは、Slim3BigTableのデータを扱うときに、特定の項目を暗号化/復号化するためのキーになります。詳しくは、データクラスの定義 - Slim3 日本語サイト(非公式)で。
logging.propertiesは、src/main/resourcesの下に作成すればOK。中身は、下記を参考に設定してみてください。

.level=FINEST

yanitime4u.level=FINEST

com.google.apphosting.utils.jetty.AppEngineAuthentication.level=WARNING
com.google.appengine.repackaged.com.google.common.base.FinalizableReferenceQueue.level=WARNING
com.google.appengine.tools.development.LocalResourceFileServlet.level=WARNING
com.google.appengine.api.labs.taskqueue.dev.UrlFetchJob.level=WARNING
org.quartz.impl.StdSchedulerFactory.level=WARNING
org.quartz.core.JobRunShell.level=WARNING
org.quartz.core.QuartzScheduler.level=WARNING
org.quartz.simpl.SimpleThreadPool.level=WARNING
org.quartz.simpl.SimpleJobFactory.level=WARNING
org.quartz.simpl.RAMJobStore.level=WARNING
org.apache.commons.httpclient.level=SEVERE
org.apache.commons.beanutils.level=WARNING
httpclient.level=WARNING

これでプロジェクト周りの設定はたぶん完了。試しに下記のコマンドを実行してみて、エラーがでなければOK。

mvn gae:run

次回は、検索機能や登録機能の実装を説明します。