JavaScriptMVCでモデルのCRUD操作をPOSTで行う方法

今日もJavaScriptMVCの小ネタです。

 

<今日のお題>

1:モデルの基本的なCRUD操作方法

2:POSTでリクエストする方法

 

  では早速本題に入ります。

 

1:モデルの基本的なCRUD操作

 まずはジェネレータで作ったモデルを見てみましょう。

 

ジェネレータで作ったモデルには既にCRUD操作用のメソッドが用意されています。

本家ドキュメントを見ると、それぞれのメソッドは以下のHTTPメソッドが使われます。

findAll  : GET

findOne : GET

create  : POST

update : PUT

destroy : DELETE

 

GETはなんか嫌だとか、PUTとかDELETEとか知らないよ、とか

様々な事情でPOSTでリクエストしたいことがあるかと思います。

そこで次のお題。

 

2:POSTでリクエストする方法

まずは更新系をPOSTにする場合。

この場合は簡単に対応できます。

updateとdestroyに指定されているURLにちょっと細工すればOK。

 

 

これで既存資産がPUT/DELETEに対応してなくても大丈夫ですね。

 

 

 

後は、JavaScriptMVCを使うアプリはそれなりの規模のアプリと思いますが、

規模が大きくなるにつれて、全リクエストで共通のパラメータを送ったり、

共通のエラー処理を行う必要が出てくることもあろうかと思います。

 

こんな場合はそれぞれのCRUDメソッドをオーバーライドしたり、

独自でリクエストを送信するメソッドを作ったりします。

この方法であれば取得系もPOSTを使うことが可能です。

この辺は改めて記事にします。ではまた次回。

javascriptMVC入門 ちょっと脱線

早めにJavaScriptMVCの記事まとめたいんですが、

時間作るのって覚悟とやる気が必要だと痛感してます、、、

 

さて、今日はちょっと脱線して、JavaScriptMVCのチュートリアル

サンプルを読み進める上でのポイントを解説しておきます。

 

JavaScriptMVCの中でも特徴があるのがコントローラの部分です。

コントローラのポイントとして、

  1:コントローラのdefaultsとoptionsプロパティ

  2:コントローラでのイベントのバインド方法

  3:追加されるjQueryヘルパーメソッド

くらいを押さえておけば処理の流れは追えます。

※ちなみにJavaScriptMVCでのjQuery拡張であるjQueryMXを使う前提です。

JavaScriptMVC自体はjQueryとは独立で利用可能です。

 

では順番に説明します。

 

1:コントローラのdefaultsとoptionsプロパティ

本家ドキュメントの「Using Controller」の部分にあるサンプルで解説します。

ドキュメントでは以下のソースが掲載されています。 

 

順に見ていきましょう。$.Controllerというのがコントローラのクラス定義です。

3つの引数を渡していますね。

$.Controller("クラス名",{/*②Static*/} ,{/*③ProtoType*/})

 ①はクラス名となります。サンプルでは"MyWidget"ですね。

後で触れるjQueryヘルパーメソッドに関わる部分です。

  

 ②はStaticメンバーの定義となります。defaultsプロパティが定義されていますね。

 ③はProtoTypeメンバーです。initメソッドと、何やら見慣れぬ

"div click" : function(div, ev){~}

というメソッド定義らしきものがありますね。

これは2:でイベントバインドの説明する時に詳しく見ていきます。

 

initメソッドは定義しておけばインスタンス生成時にコールされます。

※実はsetupという似たようなメソッドもあるんですが割愛。ドキュメント読んでね。

 

これでコントローラのクラス定義完了です。

インスタンス生成時は new MyWidget(関連づけるエレメント)みたいに

HTMLエレメントを引数に指定します。
※のちほど3:でインスタンス生成を楽に書ける方法が出てきます。

 

<ポイント>

defaultsプロパティに定義されている値は、コントローラのインスタンス生成時にoptionsプロパティに初期値として設定されます。

ただし、インスタンス生成時にパラメータを指定した場合はそちらが優先されます。

また、インスタンス生成時に指定されたパラメータはdefaultsに定義されていなくてもoptionsに保持されます。

詳しくは下記のコードを見てください。

 

 

 

 

 

 2:コントローラでのイベントバインド方法

JavaScriptMVCのコントローラは特定のHTMLエレメントと関連付けられます。

コントローラは関連付けられたHTMLエレメント(配下のエレメント含む)の

イベントを管理する役割を持っています。

 

イベントの登録はjQuery流に$('div').on('click' , function(){ /* event action*/} )などとしてもよいのですが、JavaScriptMVCでは宣言的にイベント登録を行うことが出来ます。

1:で出てきた以下のコードを再度見てみましょう。

"div click" : function(div, ev){~}
これは、
  1)コントローラに関連付けられたHTMLエレメント配下のdic要素に対し、
  2)clickイベントを登録
をしています。書式は以下の通りです。
"[セレクタ] [イベント名]" : function(div, ev){~}
[セレクタ]部分にはjQueryで利用しているセレクタを記載できます。
下記の例ではclass="title"エレメントのtapholdイベントが登録されます。
".title taphold" : function(elm, ev){~}
ちなみにイベントの第1引数にはイベント発生もとHTMLエレメントをラップしたjQueryオブジェクトが渡されます。
 
さらにここからがJavaScriptMVCらしいところ。
[セレクタ]、[イベント名]の部分をパラメータを使って動的に置き換えることが可能です。
例えば以下のように定義されているとします。
"{targetClassName} taphold" : function(elm, ev){~} 
{targetClassName}の部分は1:で説明したoptionsプロパティの内容で置き換えられます。
例えばoptions.targetClassNameに'li'が設定されていればliエレメントに対してtapholdイベントが登録されます。
defaultsと組み合わせれば再利用しやすい仕組みになりそうですね!!
 
詳細は本家ドキュメントのRapid Startが詳しいです。
英語読めない方でもソース例が豊富ですので雰囲気はつかめるかと思います。
 
 
 
3:追加されるjQueryヘルパーメソッド
コントローラのクラス定義を行うとjQueryヘルパーメソッドが追加されます。
ヘルパーメソッドはHTMLエレメントとコントローラの関連づけを楽に行えるようにしてくれます。
ヘルパーメソッドはコントローラのクラス名をもとに追加されます。
基本的にはクラス名を小文字+アンダーライン区切りにしたものです。
1:の場合はmy_widgetという名前になります。
 
$.fnに対して追加されるため、
$(".selector").my_widget();
jQueryオブジェクトに対して利用できるようになっています。
上記の書き方は
new MyWidget( $(".selector"));
と書くのと同じです。
 
※コントローラのクラス名に名前空間を指定した場合は若干独特なルールが適用されます。
例えば、コントローラのクラス名が'SimpleMemo.Controllers.MemoWidget'
の場合は"simple_memo_memo_widget"という名前になります。
この辺は改めてまとめます。
 
以上です。
少しでも本家ドキュメントを読む助けになればうれしいです。

javascriptMVC入門 その2−1

前回に引き続きjavascriptMVC入門です。

 

2:モデルの作成

MVCM、モデルを作成します。

javascriptMVCの場合、Railsなんかと同じくCRUD操作も担当しています。

 

今回はメモを表すモデルを作成します。

モデル作成の際はmodelジェネレータを使用します。

 

 

引用:本家ドキュメント

http://javascriptmvc.com/docs.html#!steal.generate

model

Creates a jQuery.Model and test files.

js jquery/generate/model App.Models.Name [TYPE] [OPTIONS]

  • App.Models.Name - The namespaced name of your model. For example, if your model is named Cookbook.Models.Recipe, the generator will createcookbook/models/recipe.js.

 

モデル名は以下で指定するとのことです。

[ルート名前空間].Models.[モデル名]

 

モデル名は「Memo」にします。

前回の通り名前空間は「SimpleMemo」となりますので、実行するのは以下のコマンドとなります。

 

$./js jquery/generate/model SimpleMemo.Models.Memo

 

実行すると、

$./js jquery/generate/model SimpleMemo.Models.Memo

      simple_memo/models/memo.js

      simple_memo/test/qunit/memo_test.js

      simple_memo/models/models.js (steal added)

      simple_memo/test/qunit/qunit.js (steal added)

      simple_memo/fixtures/fixtures.js (code added)

こんな結果が出力されます。

 

モデルオブジェクトに加えて、テスト用コードや、モデルをロードするためのコードが追記されます。

 

早速確認してみましょう。

http://localhost/jmvc/simple_memo/qunit.html

 

おなじみ?のqunitの画面が表示されますね。

f:id:febc_yamamoto:20120527112931j:plain

 

では気になるモデルの中身を確認してみましょう。

 

simple_memo/models/memo.js

steal('jquery/model', function(){

 

$.Model('SimpleMemo.Models.Memo',

/* @Static */

{

  findAll   : "/memos.json",

  findOne : "/memos/{id}.json"

  create   : "/memos.json",

  update  : "/memos/{id}.json",

  destroy : "/memos/{id}.json"

},

/* @Prototype */

{});

 

 

なんだかクラス定義っぽいのが並んでますね。

順番に解説していきます。

 

まず一番外側のsteal関数ですが、前回の説明の通りファイルの読み込みと

渡された関数の実行を行います。

'jquery/model'という指定がファイルパスとなります。

このファイル読み込み後に、もう一つの引数である関数が実行されます。

 

<補足>

前回は説明を省略しましたが、このsteal関数は'jquery/model'みたいな指定をすると、

自動的にファイルパスへと変換してくれます。

この辺のルール/お作法は改めて説明します。

 

 

では関数の中身をみてみましょう。

以下の関数を実行しています。

$.Model('モデル名(名前空間含む)' , staticなメンバー, インスタンスのメンバー);

 

これはJavaScriptMVCで提供されているクラス定義用の関数です。

実際には$.Model$.Classを継承しています。

 

JavaScriptMVCのクラス定義の特徴としては

 ・Staticメンバーの継承

 ・イントロスペクションのサポート

 ・名前空間への対応

 ・コンストラクタ用関数の提供

 ・コールバック関数の簡易な作成

などがあります。

 

詳細は本家ドキュメントを参照してください。

http://javascriptmvc.com/docs.html#!jQuery.Class

http://javascriptmvc.com/docs.html#!jQuery.Model

 

$.Model関数の第2、3引数にオブジェクトを渡すことで

クラス定義を行ってくれています。

 

staticメンバーにfindAllやらfindOneやらが定義されていますが、

これは後回しにして、とりあえずメンバーの追加をしてみます。

 

追加するのはメモ本文を表すプロパティ「memoText」関数です。

引数なしで実行するとメモ本文を取得し、

引数に文字列を指定すると、メモ本文が設定されます。

 

まずはテストを追加しましょう。

modelジェネレータで作成された「test/qunit/memo_test.js」を開きます。

 

simple_memo/test/qunit/memo_test.js

 

steal("funcunit/qunit", "simple_memo/fixtures", "simple_memo/models/memo.js", function(){

module("Model: SimpleMemo.Models.Memo")

 

test("findAll", function(){

    expect(4);

    stop();

    SimpleMemo.Models.Memo.findAll({}, function(memos){

        ok(memos)

        ok(memos.length)

        ok(memos[0].name)

        ok(memos[0].description)

        start();

    });

})

 

test("create", function(){

    expect(3)

    stop();

    new SimpleMemo.Models.Memo({name: "dry cleaning", description: "take to street corner"}).save(function(memo){

        ok(memo);

        ok(memo.id);

        equals(memo.name,"dry cleaning")

        memo.destroy()

        start();

    })

})

 

test("update" , function(){

    expect(2);

    stop();

    new SimpleMemo.Models.Memo({name: "cook dinner", description: "chicken"}).

        save(function(memo){

            equals(memo.description,"chicken");

                memo.update({description: "steak"},function(memo){

                    equals(memo.description,"steak");

                    memo.destroy();

                    start();

                })

            })

 

    });

 

test("destroy", function(){

    expect(1);

    stop();

    new SimpleMemo.Models.Memo({name: "mow grass", description: "use riding mower"}).

        destroy(function(memo){

            ok( true ,"Destroy called" )

            start();

        })

})

})

 

 

すでに単体テストが記載されています。

ここにテストケースを一つ追加します。

 

simple_memo/test/qunit/memo_test.js

 

test("class_define", function(){

    expect(3);

var memo = new SimpleMemo.Models.Memo();

  ok(memo.getMemoText()   , "Memo getMemoText defined");

  ok(memo.setMemoText()   , "Memo setMemoText defined");

 

  memo.setMemoText("test");

  ok(memo.getMemoText() == "test" , "Memo memoText setted/getted");

})

 

getter/setterの確認となっています。

実行するとエラーになりますね。

早速実装します。

 

simple_memo/models/memo.js

steal('jquery/model', function(){

 

$.Model('SimpleMemo.Models.Memo',

/* @Static */

{

  findAll   : "/memos.json",

  findOne : "/memos/{id}.json"

  create   : "/memos.json",

  update  : "/memos/{id}.json",

  destroy : "/memos/{id}.json"

},

/* @Prototype */

{

    getMemoText : function(){

        return this.memoText;

    },

    setMemoText : function(val){

        this.memoText = val;

    }  

});

 

});

 

グリーンバーを獲得できましたね。

 

続きは後ほど編集します、、、

 

javascriptMVC入門 その1

 

javascriptMVCとはクライアントサイドでのMVC開発を強力にサポートしてくれるフレームワーク+ツールセットです。

http://javascriptmvc.com/

 

javascriptMVCの主な構成要素は以下5つ

 ・javascriptMVC本体

 ・StealJS:本家によると「A code manager」とのこと。依存性管理やコードクリーニング、デプロイなど

 ・jQueryMXjQueryの拡張

 ・FuncUnit Webテストフレームワーク

 ・DocumentJS ドキュメンテーションエンジン。javadocrdocみたいな感じ

 

なにぶん日本語の解説が少ない+本家のドキュメントが若干散らかっている部分があるんで、

チュートリアルαとして本家のTODOアプリみたいなのを作りながら解説します。

 

 

<作るアプリの概要>

 ・短い文章をメモとして登録/更新/削除/一覧ができる

 ・メモはセッションストレージに保存

 ・jQueryMobileを利用してモバイル用UIとして作成

 

実はCRUDをするだけならscaffold出来るんですが、、わかりやすさの為にあえて作ります。

また、javascriptMVCLESSCoffeeScriptもサポートしているんですが、

今回はシンプルにするために使いません。

 

<インストール&環境準備>

zipをダウンロードするか、gitで取得してくるか。

今回はお手軽にzipをダウンロードします。

http://javascriptmvc.com/

の画面右上の方のDownloadから取得します。

 

zipをダウンロードしたら展開し、そのディレクトリへ移動。

/jmvcに配置

ついでにApacheのドキュメントルートにシンボリックリンクを作成しておきます。

これで「http://localhost/jmvc/」でjavascriptMVCを配置したディレクトリが参照できる。

$ cd /var/www/

$ sudo ln -s /jmvc jmvc

 

 

<アプリ作成>

今回作るアプリの名前は「SimpleMemo」とします。

これにより、

 ・アプリのルートディレクトリ名は「simple_memo

 ・モデルやコントローラなどの属するルート名前空間は「SimpleMemo

となります。

この後使う「app」ジェネレータが「SimpleMemo」みたいな

キャメルケースを渡すことが出来ないため、注意が必要です、、

 

本家ドキュメントにもちょっとだけ注意事項が触れられていますが、

この現象、バグっぽいんですよね。

引用:本家ドキュメント

http://javascriptmvc.com/docs.html#!steal.generate

 

 

app

Creates a JavaScriptMVC application structure.

js jquery/generate/app path/to/app [OPTIONS]

  • path/to/app - The lowercase path you want your application in. Keep application names short because they are used as namespaces. The last part of the path will be taken to be your application's name.

 

この説明でキャメルケース渡す方が悪いっちゃ悪いと思いますが、、

うまいこと対応してほしいもんです。

 

という訳で、名前に気をつけつつアプリ作成に入ります。

 

1:アプリケーションのひな形作成

まずはappジェネレータを使ってひな形を作ります。

先ほども触れた通り、指定するアプリ名は「simple_memo」とし、以下のコマンドを実行します。

 

$./js jquery/generate/app simple_memo

 

出来上がるファイルは、、

simple_memo/             // アプリのディレクト

  simple_memo.css        // 当アプリのcssファイル

  simple_memo.html       // 当アプリのメインhtmlファイル

  simple_memo.js     // 当アプリのメインjsファイル。主に他のファイルの読み込みを行う

  docs/                  // APIドキュメントの生成先ディレクト

  fixtures/              // AJAXリクエストのシミュレーション用js

  funcunit.html          // FuncUnitを使ったテストの実行用ページ

  models/                // モデル&データレイヤ

  qunit.html             // qunitによるテスト実行用ページ

  scripts/               // コマンドラインスクリプト(中身の説明は省略)

  test/                  // テスト用js

 

 

 

確認のため「http://localhost/jvmc/simple_memo/simple_memo.html」をブラウザで確認。

念のためリンク切れなどないかFireBugなどで確認しておく。

 

まずはsimple_memo.htmlを開いて、不要なものを消しちゃいます。

今のところ重要なのは以下のscriptタグ。

<script type='text/javascript'

        src='../steal/steal.js?simple_memo'>

</script>

 

以外は消しちゃいましょう。こんな感じになってればOK

ちなみにlang="en"になってるんで"ja"に変更しましょう。ついでにcharsetも追加します。

<!DOCTYPE HTML>

<html lang="ja">

  <head>

    <meta charset="UTF-8" />

    <title>simple_memo</title>

  </head>

 

  <body>

    <div data-role="page"></div> <!--  -->

    <script type='text/javascriptpt'

            src='../steal/steal.js?simple_memo'>

    </script>

  </body>

 

 </html>

 

気になる'steal.js?simple_memo'ですが、?以降をアプリケーション名として解釈し、

メインのjsファイルを読み込んでくれます。

読み込み対象はアプリケーション名.jsファイルです。

今回読み込まれるのは「simple_memo.js」となります。

 

ではsimple_memo.jsをのぞいてみましょう。

steal(

    './simple_memo.css',           // application CSS file

    './models/models.js',       // steals all your models

    './fixtures/fixtures.js',   // sets up fixtures for your models

    function(){                 // configure your application

 

})

 

steal関数にファイルパスと関数を渡しています。

このsteal関数は単純に、渡されたパスのファイル読み込み+渡された関数処理を行うだけです。

読み込み順序なんかがある場合は以下のように書きます。

steal(

// ファイルパスや関数・・・(1)

).then(

    // (1)が完了した後に実行される。

    // (1)と同じくファイルパスや関数を渡す ・・・(2)

).then(

    // (2)が完了した後に実行される。

    // (1)と同じくファイルパスや関数を渡す 

)

 

 

現状のsimple_memo.jsではCSSファイルやその他のJSファイルなんかを読み込んでいますね。

今回jQueryMobileを使うため、必要ファイルを追記します。

jQueryMobileのグローバル設定の為に、

1:jQuery本体の読み込み

2:jQueryMobileのグローバル設定用イベントを登録

3:jQueryMobileの読み込み

となるようにします。

 

steal(

    './simple_memo.css',           // application CSS file

    './models/models.js',       // steals all your models

    './fixtures/fixtures.js',   // sets up fixtures for your models

    'http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css',   // jQueyMobile用CSS

    'http://code.jquery.com/jquery-1.7.2.min.js',                        // jQuery本体

    function(){                 // configure your application

    }

).then(                                                                  // グローバル設定用イベント

    function(){

        $(document).bind("mobileinit", function(){

            $.mobile.loadingMessage = '読み込み中';

            $.mobile.pageLoadErrorMessage = '読み込みに失敗しました';

            $.mobile.dialog.prototype.options.closeBtnText = '閉じる';

            $.mobile.selectmenu.prototype.options.closeText= '閉じる';

            $.mobile.listview.prototype.options.filterPlaceholder = '検索文字列';

            $.mobile.page.prototype.options.backBtnText = '戻る';        

        });

    }

).then(

    'http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css',   // jQueryMobile本体

)

 

 

確認のためsimple_memo.htmlをブラウザで開いて、cssjsが読み込めているか確認しておきます。

 

<余談>

なお、simple_memo.html中の※1の部分ですが、これがないとdev.jsの読み込みエラーが発生します。

 

このエラーについてgoogle先生に聞いてみると、、、

http://forum.javascriptmvc.com/topic/integration-jquery-mobile-js-mvc

http://forum.javascriptmvc.com/topic/jquery-mobile-or-zeptojs

こんなのが。おんなじ症状っぽいですね。

何らかの条件下でjqueryMobileの初期化処理が行われるとエラーになるっぽい。

とりあえずdata-role="page"のエレメントを追加しておけば大丈夫だったんで、後で調査してみます。

 

長くなりそうなんで、続きは次回。

 

Heroku/Cedar上でSAStruts + iOSアプリしてみる その2

昨日の続き。

今日は問題ありありだったiOS側。

まずは手順の再確認。

  1. Write Your Web API App
  2. Declare Gem Dependencies With Bundler
  3. Declare Process Types With Foreman/Procfile
  4. Store Your App in Git
  5. Deploy to Heroku/Cedar
  6. Create Your iOS Client App
  7. Declare iOS Dependencies with CocoaPods
  8. Write A Table View Controller
  9. Configure AppDelegate
  10. Build & Run

昨日の時点で5まで終わっているので6から。

 

6. Create Your iOS Client App

単純にXCodeで新規プロジェクトを作成するだけの部分。

元ネタに従って進めましょう。

 

7.Declare iOS Dependencies with CocoaPods

MacRuby入れて、macgemでcocoapods入れろとのこと。

でもLionの場合エラーが出て進めない。

 

調べてみるとデフォルトで入っているruby使えばいいとのこと。

gem install cocoapods

pod setup

すればOK。

Podfileの作成とpod installは元ネタのままでOK。

 

8.Write A Table View Controller

XCodeでファイルを追加すればいいのね♪

じゃあご指定の“UIViewController subclass”を選んで、、、、ないじゃない。

実はXCode4.3で変わってる部分。

慌てずに「Objective-C class」テンプレートを選択しましょう。

ここからUITableViewのサブクラスと出来るように選択肢が出てきます。

 

 

9.Configure AppDelegate
10.Build & Run

元ネタのままでOK。

実行結果はこんな感じ。

 

f:id:febc_yamamoto:20120306222353j:plain

日本語もバッチリ。

以上です。

 

次回はHeroku/Cedar上のSAStrutsを利用した

簡易ステージング環境構築を書きたいな〜。

 

Heroku/Cedar上でSAStruts + iOSアプリしてみる その1

前回までに引き続き、Heroku/Cedar上でSAStrutsを動かしてみる。

今回はmacbook proの環境をLion+XCode4.3にしたので、せっかくなのでiOSアプリと連携してみる。

 

元ネタはこちら

Getting Started with iOS Development using Sinatra on Heroku / Cedar

元ネタの環境構築やらトラブルシューティングをのぞいた手順。

  1. Write Your Web API App
  2. Declare Gem Dependencies With Bundler
  3. Declare Process Types With Foreman/Procfile
  4. Store Your App in Git
  5. Deploy to Heroku/Cedar
  6. Create Your iOS Client App
  7. Declare iOS Dependencies with CocoaPods
  8. Write A Table View Controller
  9. Configure AppDelegate
  10. Build & Run

 

Heroku側は前回までと同様SAStrutsを使う+今回はDB使わないので、

今回のHeroku側に上げるアプリ作成手順は、

  1. Doltengでプロジェクト作成
  2. Jetty Runner追加
  3. Procfileの作成
  4. JSONを返すメソッドの実装
  5. ローカルでの動作確認
  6. Heroku/Cedarへのアップロード

となります。

元ネタではSinatraを使ってJSONを返していますので、

4.「JSONを返すメソッドの実装」にてSAStrutsJSONを生成して返す処理だけ実装します。

それ以外は前回までと同様です。

 

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が出ました。

その場合、web.xmlからrequestDumpFilterをコメントアウトしておくとよさそうです。後で調べる。