Heroku/Cedar上でSAStruts + iOSアプリしてみる その1
前回までに引き続き、Heroku/Cedar上でSAStrutsを動かしてみる。
今回はmacbook proの環境をLion+XCode4.3にしたので、せっかくなのでiOSアプリと連携してみる。
元ネタはこちら
Getting Started with iOS Development using Sinatra on Heroku / Cedar
元ネタの環境構築やらトラブルシューティングをのぞいた手順。
- Write Your Web API App
- Declare Gem Dependencies With Bundler
- Declare Process Types With Foreman/Procfile
- Store Your App in Git
- Deploy to Heroku/Cedar
- Create Your iOS Client App
- Declare iOS Dependencies with CocoaPods
- Write A Table View Controller
- Configure AppDelegate
- Build & Run
Heroku側は前回までと同様SAStrutsを使う+今回はDB使わないので、
今回のHeroku側に上げるアプリ作成手順は、
となります。
元ネタではSinatraを使ってJSONを返していますので、
4.「JSONを返すメソッドの実装」にてSAStrutsでJSONを生成して返す処理だけ実装します。
それ以外は前回までと同様です。
4.「JSONを返すメソッドの実装」
単純にJSON文字列を返すメソッドを実装します。
今回実装する機能はこれだけなので、index/IndexActionに実装してしまいます。
package com.febc.action;
import org.seasar.struts.annotation.Execute;
import org.seasar.struts.util.ResponseUtil;
public class IndexAction {
@Execute(validator = false)
public String index() {
ResponseUtil.write("{\"sushi\":[\"鮪\",\"鰤\",\"雲丹\",\"鯖\",\"海老\",\"鮭\",\"鯛\"]}", "text/json");
return null;
}
}
元ネタではローマ字表記の寿司ネタですが、
本場日本ですから当然漢字表記します。
※おとなしくオブジェクトをJSON変換すればよかったんですが、
楽しようと思って手書きでJSONを書いた結果、フォーマットが正しくなく、
iOS側で読み込めないという事態が発生しました。
ダブルクォートをシングルクォートにしてたのがよくなかったらしい。
これで2時間くらい飛びました。
後はローカルでforeman startして動作確認できたらHeroku側にpush。
この辺は前回までと全く一緒です。
そしてここからが問題のiOS側。
基本的に元ネタをたどればいいはずなのにちょいちょいコケるポイントがありました。
続きはまた次回。
Heroku/Cedar上でSAStruts+S2JDBCを動かす その2
前回の続き。
4.Procfileの作成
これも元ネタのままでOK。以下の内容で「Procfile」という名前でファイル作成。プロジェクトのルートディレクトリにおいておく。
web: java $JAVA_OPTS -jar target/dependency/jetty-runner.jar --port $PORT target/*.war
5.ローカルでの動作確認
これも元ネタのままでOK。
6.Heroku/Cedarへのアップロード
元ネタに加えてDBのインポートを行う。
インポートはこちらを参考に。
後はお決まりのgit addからpushまで。
git init
git add .
git commit -m 'init'
# --stack cedarをつけること。
heroku create --stack cedar
git push heroku master
# プロセスが起動しているか確認
heroku ps
# ログの確認
heroku logs
※実際にデプロイすると、いくつかの画面でExceptionが出ました。
Heroku/Cedar上でSAStruts+S2JDBCを動かす その1
元ネタはこちら。
Getting Started with Spring MVC Hibernate on Heroku/Cedar
Heroku上でSpring MVC Hibernateが動くなら、SAStruts+S2JDBCも動くはず。
ということで実験。
まずは元ネタから手順を確認。
- Create a Java App That Uses Spring MVC and Hibernate
- Modify Database Configuration
- Add Jetty Runner
- Declare Process Types in a Procfile
- Run Your App Locally
- Deploy to Heroku/Cedar
- Doltengでプロジェクト作成
- データベース設定変更
- Jetty Runner追加
- Procfileの作成
- ローカルでの動作確認
- Heroku/Cedarへのアップロード
主な違いは
といったところ。詳細は各項目ごとの説明を参照。
1.Doltengでプロジェクト作成
このあたりを参考にプロジェクト作成。もちろんSAStruts+S2JDBCにしておく。
今回はDB上にテーブルを作成し、Doltengのscaffoldを利用する。
まずはPostgreSQL上でCREATE TABLEしておく。
今回作ったのは以下のシンプルなテーブル。
CREATE TABLE users
(
id serial NOT NULL,
first_name character varying(100),
last_name character varying(100),
CONSTRAINT pk_users PRIMARY KEY (id )
)
このテーブルを元にscaffoldします。
scaffoldについてはこのあたりを参照。
※もちろんjdbc.diconとs2jdbc.diconにURLやユーザー名、パスワードなどの設定が必要。あらかじめ設定しておきましょう。
2.データベース設定変更
Heroku上ではDatabase接続情報は環境変数「DATABASE_URL」に格納されている。
フォーマットは以下のとおり。
postgres://user:password@hostname/path
元ネタでは
<bean class="java.net.URI" id="dbUrl">
<constructor-arg value="${DATABASE_URL}"/>
</bean>
として環境変数を利用してURIインスタンス(dbUrl)を生成し、
データベース接続設定ファイルにて
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="#{ 'jdbc:postgresql://' + @dbUrl.getHost() + @dbUrl.getPath() }"/>
<property name="username" value="#{ @dbUrl.getUserInfo().split(':')[0] }"/>
<property name="password" value="#{ @dbUrl.getUserInfo().split(':')[1] }"/>
...
という形で利用している。
これをS2JDBC用に置き換えるため、以下のヘルパークラスを作成する。
package com.febc.heroku.util;
import java.net.URI;
import java.net.URISyntaxException;
public class HerokuEnvironmentHelper {
private static HerokuEnvironmentHelper instance;
public static HerokuEnvironmentHelper getInstance()
throws URISyntaxException {
if (instance == null) {
instance = new HerokuEnvironmentHelper();
}
return instance;
}
private URI DB_URI;
private static final String DB_URI_ENV_NAME = "DATABASE_URL";
private HerokuEnvironmentHelper() throws URISyntaxException {
DB_URI = new URI(System.getenv(DB_URI_ENV_NAME));
}
public String getUrl() {
return "jdbc:postgresql://" + DB_URI.getHost() + DB_URI.getPath();
}
public String getUsername() {
return DB_URI.getUserInfo().split(":")[0];
}
public String getPassword() {
return DB_URI.getUserInfo().split(":")[1];
}
}
これでdiconファイル中に環境変数からのDB接続情報を設定できる。
jdbc.diconはこんな感じ。
<component name="xaDataSource"
class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
<property name="driverClassName">
"org.postgresql.Driver"
</property>
<property name="URL">
@com.febc.heroku.util.HerokuEnvironmentHelper@getInstance().url
</property>
<property name="user">
@com.febc.heroku.util.HerokuEnvironmentHelper@getInstance().username
</property>
<property name="password">
@com.febc.heroku.util.HerokuEnvironmentHelper@getInstance().password
</property>
</component>
ローカルで動かす場合にも環境変数「DATABASE_URL」が必要となるので設定しておく。
3.Jetty Runner追加
これは元ネタのままでOK。Doltengでプロジェクトを作成しているためpom.xmlも生成されているはず。plugins配下に以下を追記。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>copy</goal></goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-runner</artifactId>
<version>7.4.5.v20110725</version>
<destFileName>jetty-runner.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
ついでに、依存jarについてもここで記載しておく。
dependencies配下に以下を追加。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901.jdbc3</version>
</dependency>
続きは次回へ。