Upload
tsuyoshi-yamamoto
View
2.027
Download
1
Embed Size (px)
DESCRIPTION
Citation preview
G* on GAE/J 挑戦編
2009/08/22 @Tokyo
def speaker = new Cast(name:”T.Yamamoto”,version:”G*S-2009-08-22”)
自己紹介名前:山本 剛 (やまもとつよし)
所属:株式会社ニューキャストDTP、組版屋、印刷業界向けWebアプリ開発など。案件は90%Grailsを使ってます。
JGGUG(じぇいがぐ) 名古屋支部長です。「Grails徹底入門」9-11章を書きました。 Grails Acegi Plugin作った人。
ブログhttp://d.hatena.ne.jp/mottsnite/
第零幕
Grails!?
JavaEEで実績のあるSpringフレームワークやHibernateをベースに、Groovyを活用して効率よくJavaEE開発を行うことのできる、フルスタックフレームワークです。
Grails-1.2M2Spring3に更新@Transactionalでのメソッド単位のトランザクションの実装ダイナミックファインダでのBoolean値の機能を追加GORMにhasOneマッピングをサポート名前付き問合せ定義が可能GORM 厳密なバリデーションエラーWARデプロイでのGSPプリコンパイルマルチ組込コンテナサポート、デフォルトはTomcatに!i18nでのクラス名プロパティ名をハンドル名称付きURLマッピングプロジェクトドキュメントエンジンプラグインメタジェネレータ
では、Grailsを、
体験してみましょう。
第壱幕
GrailsでWebアプリ作ってみよう
準備どのようなWebアプリケーション開発を作るか?
今回のテーマ「イベント告知アプリ!?」を作ってみる
プラン「イベント告知アプリ!?」イベントの登録・配信がおこなえる
準備使いたい機能を持ったプラグインの現時点での候補Calendaryui-css •Tips
•必要機能に適したプラグインの有無を確認。•プラグインを活用!•無駄を無くす。•プラグインからアイデアをもらう。
図
設計必要項目ドメインクラスイベントを収納するテーブル
コントローラリスト表示 (list)作成・編集 (entry)editsave
詳細表示 (show)他ロゴレイアウト
プロジェクトを作成Grailsプロジェクトを作成
BuildConfig.groovy (オススメ) 作業ディレクトリやビルド時の環境指定が可能。grails-app/conf/BuildConfig.groovyファイルを作成
DBの設定 grails-app/conf/DataSource.groovyファイルを編集
$ grails create-app eventer$ cd eventer
grails.project.plugins.dir="work_tmp/plugins"grails.project.work.dir="work_tmp/work"
development { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:work_tmp/devDB;shutdown=true"
試し起動$ grails run-app
ドメインクラスモデル → 詳細(ドメインモデル) → ドメイン設計1. 必要な項目
イベントタイトル - eventName開催日 - eventDate開催時間など - eventDesc場所 - place主催団体名 - groupName内容 - content
2. 実際にドメインクラスを作る
3. コントローラを作成
$ grails create-controller org.jggug.Event
$ grails create-domain-class org.jggug.Event
Event.groovypackage org.jggug
class Event {
/** イベントタイトル */ String eventName /** 開催日 */ Date eventDate /** 開催時間など */ String eventDesc /** 場所 */ String place /** 主催団体名 */ String groupName /** 内容 */ String content Date dateCreated Date lastUpdated
static constraints = { }}
EventController.groovypackage org.jggug
class EventController { def scaffold = true}
起動してみましょう!$ grails run-app
調整!idをuuid.hexにする。
バリデーション全て null不許可、空白不許可contentに4000文字制限
Event.groovyclass Event implements Serializable {
static mapping = { id generator:'uuid.hex', params:[type:'string'] } String id...
static constraints = { eventName nullable:false,blank:false eventDate nullable:false,blank:false eventDesc nullable:false,blank:false place nullable:false,blank:false groupName nullable:false,blank:false content nullable:false, blank:false,maxSize:4000 dateCreated display:false lastUpdated display:false }
調整! i18n (1.2M2の新機能)i18n (1.2M2の新機能)messages_ja.propertiesにフィールド名称を定義
コマンドとか有れば良いのに....無いのでテキストエディタで置換!
/** イベントタイトル */String eventName
/** 開催日 */Date eventDate
/** 開催時間など */String eventDesc
event.label = イベントevent.eventName.label = イベントタイトル
適当だけど/\*\*(.*)\*/\n(.*) (.*)
event.$3.label = $1
event.eventName.label = イベントタイトル event.eventDate.label = 開催日 event.eventDesc.label = 開催時間など
ドメインが完成
STEP.4 コントローラとビューgenerate-all して各ソースファイルを編集します。
起動します。
$ grails generate-all org.jggug.Event
$ grails run-app
調整ポイント!カレンダープラグインで日付フォームをかっこよくリスト調整必要な部分だけ残して見た目調整。詳細表示デザイン調整!レイアウト調整
カレンダープラグイン開催日のフォーム調整
★<head>タグの中に<calendar:resources lang="en" theme="tiger"/>
★対象の場所に<calendar:datePicker name="eventDate" defaultValue="${eventInstance?.eventDate}" dateFormat="%Y/%m/%d" />
★カレンダープラグインをインストール$ grails install-plugin calendar
リスト調整
こんな感じに。タイトルはリンクに
詳細表示調整
レイアウト調整横にメニューのあるレイアウトに調整yui-cssを使う!
http://grails.jp/sample/grails-yui-css-2.7.0-M2.zip
コマンドを実行
★yui-cssのプラグイン(非公式)をインストールgrails install-plugin http://grails.jp/sample/grails-yui-css-2.7.0-M2.zipgrails yui-css
<head>内の以下の部分 content=”main”を “yui-t1”に変更<meta name="layout" content="main" />
<meta name="layout" content="yui-t1" />
メニュー調整・・・・・
STEP.5 完成いろいろやり残しは有りますが・・
デプロイするとTomcat等のアプリケーションサーバーで運用可能です。$ grails wareventer-0.1.war が生成されます。
第弐幕
GrailsでGAE/J
GAEアカウント登録App Engineのページへ!http://code.google.com/intl/ja/appengine/
GAE登録Googleのアカウントでログイン。アカウントが無い場合は作成。
GoogleアカウントGoogleアカウントが無い場合は登録してください。
ログインするとログイン
App Engineのトップページアプリケーション作成画面。Create an Applicationをクリック
認証メール携帯電話のメールアドレスを登録携帯メールに認証コードが送られてくるので、次の画面でコードを入力
GAEアプリ作成アプリケーション作成画面
GrailsをGAEに!
Grailsには、GAEに対応させるためのプラグインが用意されています。
AppEngine
Plugin
AppEngine PluginGrailsをGAE/Jに対応させるプラグイン機能
インストール時にGAEに必要なファイル生成デプロイ用のコマンドスカッフォルドテンプレートJDOとJPAに対応認証設定 → Config.groovyに設定
AppEngine Pluginインストール前に必要な設定
Google App Engine SDK設定ダウンロード&解凍http://code.google.com/appengine/
AppEngineSDKの場所を指定。環境変数 APPENGINE_HOME 又は、config/BuildConfig.groovyにgoogle.appengine.sdkで指定
export APPENGINE_HOME=/opt/appengine-java-sdk-1.2.2
google.appengine.sdk='/opt/appengine-java-sdk-1.2.2'
インストールと設定インストール!$ grails install-plugin app-engine
インストール途中で質問に答えます。Do you want to use JPA or JDO for persistence? (jpa, jdo)jpa
インストールされるとgrails-app/conf/以下にそれぞれのファイルが追加されます。datastore-indexes.xmlpersistence.xml
★grails-app/conf/Config.groovyにGAEのアプリケーション名を記述google.appengine.application="jggugv4"
★Grailsプロジェクトのバージョンをセット
GORM-JPA
GORM-JPA PluginJPAプラグインは3種類ある…
Hibernate JPA Provider PluginJPA PluginGORM-JPA Plugin ← これを使います。
できることGORMと同じsave(),list()等のメソッドが利用できる(※一部未対応、)
できないことドメインクラスと同じmapping定義ドメインの定義には、JPAアノテーションを利用Criteria (※JPA1.0で未対応なため)
GORM-JPAインストールインストール! $ grails install-plugin gorm-jpa
resources.groovyにentityManagerFactoryとtransactionManagerを追記entityManagerFactory(org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean) { beanClassLoader = ref("classLoader")}
transactionManager(org.springframework.orm.jpa.JpaTransactionManager) { entityManagerFactory = entityManagerFactory }
何故かdatanucleus-enhancer*.jarが入っていないのでコピーcp $APPENGINE_HOME/lib/tools/orm/datanucleus-enhancer-1.1.4.jar lib
起動!ちょっとまった!起動したいのですが、そのままだと色々と問題が。JPA用にドメインクラスの調整が必要コントローラも若干調整が必要
ドメインクラスの調整通常のGrailsドメインクラスでは、JPAで使うことはできません。若干の修正が必要です。JPA用のアノテーションを追記
import org.datanucleus.jpa.annotations.Extensionimport javax.persistence.*;
@Entityclass Event implements Serializable {
@Id @GeneratedValue (strategy = GenerationType.IDENTITY) @Extension (vendorName = "datanucleus",
key = "gae.encoded-pk", value = "true") String id /** イベントタイトル */ @Column //全てのフィールドに付加 String eventName
コントローラの調整これが正解なのかは検証中ですが。アクションクロージャsaveだけ編集。
def save = { def eventInstance = new Event(params) Event.withTransaction{ if(eventInstance.save(flush:true)) { flash.message = "Event ${eventInstance.id} created" redirect action:"show", id:eventInstance.id } else { render view:'create', model:[eventInstance:eventInstance] } }}
起動テスト起動してみましょう!
準備$ grails set-version 1
起動$ grails app-engine run
動いた!
だが、
ローカル
反省点・まとめ まあ、どうにかローカルで動きました。が・・
Stringは500文字までなので・・・対応方法は有るのだけど、よく分からなかったので放置。GORM-JPAプラグインで完全サポートされると思うので待ちます。
GAEにアップデート・・・動作しない。1.2-M2だと、ログ関係があやしい・・たしかに、1.1.1では動いていた・・・早急に対応期待
もう少しGAE/Jを勉強しないと。
くやしいです!
ホントにムリ?
1.2-M2だと、ログ関係があやしい問題を探ってみた。
どうやらこれが問題点
1.2-M2だと、ログ関係があやしい回避方法。該当部分を修正して、grailsをビルドする。LoggingGrailsPlugin.groovyを修正単純に該当箇所コメントアウトバージョンが、1.2-SNAPSHOTになる。application.propertiesのGrailsバージョン変えるGRAILS_HOMEも変更そして実行。
$ grails app-engine package$ rm target/war/WEB-INF/lib/jul-to-slf4j-1.5.6.jar$ appcfg.sh update ./target/war
動きました!
まとめGAE/J・・・ローカルとサーバで違いがあるね。どうなんですかね???
Grails自体にバグがあると対応は大変です。まだ、一般向けでは無いと思う。
でも、これ完成したらスゴイと思います。
もっとライトな
Groovy on GAE/J
第参幕
Gaelyk(GroovyでGAE/J)
※ここでは、Google App Engineのコマンドを使用します。App Engine SDKの設定が必要です。
export APPENGINE_HOME=/opt/appengine-java-sdk-1.2.2export PATH=$PATH:$APPENGINE_HOME/bin
動作確認$ dev_appserver.sh -h$ appcfg.sh -h
※Windowsでは、.sh→.cmd
Gaelyk - ゲーリックGaelykとは、
GAE/J用の軽量Groovy開発ツールキットです。GroovyテンプレートとGroovyletで構成されています。ビューとコントローラGroovletsとTemplateServletを拡張したクラスで実現ビュー:GaelykTemplateServlet拡張子gtplのプレゼンテーション層
コントローラ:GaelykServletGaelykTemplateServletとGaelykServletにGAE/Jで使用するサービスなどがServletBindingにバインドされています。GAE/JのサービスにもCategoryを使用してメソッドが拡張追加されています。
セットアップGaelykテンプレートプロジェクトをダウンロードhttp://gaelyk.appspot.com/download/
テンプレートプロジェクトです。そのまま解凍して仕様します。gaelyk-template-project-0.1.zipを解凍。
内容 プロジェクトbuild.groovy & srcAntBuilderで実装されてる簡単なビルド用プログラム。srcフォルダに配置した、GroovyとJavaのソースのコンパイルに使用。
warこのディレクトリがデプロイされます。
内容 warディレクトリこのディレクトリに、ビューの*.gtplと、css、images等のファイルを配置します。WEB-INFappengine-web.xmlGAEの定義ファイル
web.xml/groovy/ここに*.groovy配置
/includes/ - インクルードファイル//lib/ - *.jar/classes/
設定appengine-web.xml<application>タグの中身を自分のアプリケーション名称に変更<version>を指定<static-files> 拡張子を変えるときはここも変更
起動してみましょう
http://localhost:8080/をブラウザで表示
ローカルで起動テンプレートプロジェクトのルートで、$ dev_appserver.sh ./war
※Windowsでは、.sh→.cmd
さわってみよう
テンプレートJSPやGSPと同じようなもの。Groovyコードが書けます。<% /* some code */ %>${value}でGString書けます。<%=hoge %>も使えます。printとprintlnもOK。
GaelykTemplateServletソース
GaelykのGroovletsGroovyServletを拡張したGroovyスクリプト
Viewテンプレートへのデリゲートrequest.setAttribute 'list', [1, 2, 3, 4]request.setAttribute 'date', new Date() forward 'display.gtpl'
GaelykServletソース
Eager変数request : HttpServletRequestresponse : HttpServletResponsecontext : ServletContextapplication : contextと同じsession : HttpSessionを返します。 request.getSession(false) と同じです。params : フォームパラメータのマップheaders : 全てのリクエストヘッダのマップ
Lazy変数out : PrintWriterを返す。 response.getWriter()への速記sout : ServletOutputStreamを返す。 response.getOutputStream() への速記html : MarkupBuilderを返す。 new MarkupBuilder(response.getWriter()) への速記
注入済みGAEのサービスdatastoreService : DatastoreサービスmemcacheService : MemcacheサービスurlFetchService : URLFetchサービスmailService : メールサービスimagesService : ImagesサービスuserService : ユーザサービスuser : ログイン中のユーザ (ログインしていない場合は null )
low-levelデータストアAPIEntityクラスを使ってサクサクデータストアimport com.google.appengine.api.datastore.Entity
def person = new Entity("person")
person['name'] = "やまもとつよし"println person['name']
person.age = 31println person.age
//保存person.save()
//削除person.delete()
//リストdef q = new Query('person')def list = datastoreService.prepare(q).asList(
Builder.withLimit(20).offset(0) )
Demo/デモ
注意点・ゲーリックまとめ*.gtplの文字化け回避
file.encodingのみではだめっぽい。groovy.source.encodingも指定してね。
意外と楽しいので、ゲーリック中毒注意!
<system-properties> <property name="file.encoding" value="UTF-8"/> <property name="groovy.source.encoding" value="UTF-8"/></system-properties>
まとめG*なGAE/J開発では、どれを選択するべき?ものすごく単純なWebアプリを作る場合は、Gaelyk
様々なプラグインを活用して高度なWebアプリを作りたい場合は、Grails/AppEngine
Grailsをそのままクラウドへの場合はCloudFoundry/EC2