play2 の変更点   

  • 追加された行はこの色です。
  • 削除された行はこの色です。
  • play2 へ行く。

* Play2.2(Java)[#l54a0039]
play2を java で windows で eclipse で開発する方法

* インストール [#e5b441bc]
install は便宜上 c:\ に行っているが、"Program Files"など スペースが入っていないところが望ましい

*** eclipse [#r42a9f51]
play 用の java の記述は癖があるので、新規に入れた方が良い~
[[play2/eclipse]]

*** java [#n9f26784]
play は eclipse と コマンドラインの双方でコンパイルすることになる~
それらのバージョンが違っていると無駄にはまるので注意~

OS の環境設定で下記を追加
|JAVA_HOME | c:\java\jdk1.8.0_40       |
|PATH      | c:\java\jdk1.8.0_40\bin   |

 > java -version 
 > javac -version 

でバージョンを確認

*** play2 [#c065a76e]
 wget http://downloads.typesafe.com/play/2.2.3/play-2.2.3.zip
 unzip play*.zip
 mv play-2.2.3 "c:\play2"
 cd "c:\play2"
 mkdir workspace 

OS の環境変数設定で下記を追加
| PATH | c:\play2; |

* play プロジェクト作成 [#s3ee38ca]

[[play2/HelloPlay]]

* eclipse に取り込み [#oeca93fa]

[[play2/eclipsify]]

* MVC と ORM のサンプルプログラム [#o3ddd1f0]
[[play2/sample]]

//-------------------------------------------------------------------------
* バージョン管理 [#v84be4ad]
- とりあえず svn
- SVN にあげてはいけないもの (ignore の設定)
|logs               |
| project/project|
| project/target|
| target|
| tmp|
| .history|
| dist|
| /.idea|
| /*.iml|
| /out|
| /.idea_modules|
| /.classpath|
| /.project|
| /RUNNING_PID|
| /.settings|

* sbt [#z3dfa003]
- play では 外部の jar ライブラリのインストールに sbt を使用する
- build.sbt ファイルに maven の jar リポジトリのパスを追記する
- [[maven]] のようなもの
- eclipse の .classfile を各人の環境に合わせて作ってくれる
- バージョンも指定できるので動かなくなる事故が少なくなる
- ''注:compile が通らない状態だと play eclipse が失敗する''~
使うライブラリのコードは一旦コメントアウトしておくこと

[[maven]]にならって日本語roma変換ライブラリ icu4j を追加する例~
+ icu4j を検索
 http://mvnrepository.com/
 icu4j
SBT のタブを見ると..
 libraryDependencies += "com.ibm.icu" % "icu4j" % "53.1"
と書いてある
+ build.sbt に追記
 libraryDependencies ++= Seq(
  javaJdbc,
  javaEbean,
  "com.ibm.icu" % "icu4j" % "53.1",
  cache
 )
+ play コンソールに入る
 [hello] $ clean
 [hello] $ eclipse with-source=true with-javadoc=true
+ プロジェクトを右クリック -> F5 
+ 参照ライブラリに  icu4j-53.1.jar が追加されている
+ 処理を追記
''app/controllers/Application.java''
  public static Result index() {
        return ok(Transliterator.getInstance("Any-latin").transliterate("ほげ"));
  }
+ ソース保管で import が追加されればOK
(ちなみに、SHIFT+F2 で javadoc 参照 , F3 でソースコードの参照もできる)

* テスト [#ge51b019]
[[play2/test]]

// -------------------------------------------------------------------
* scala.html [#gd596b81]
はっきりいって play で初めて scala に触れた Java プログラマにはさっぱり理解できない~
どこまでが scala 部分で、どこからが play の構文なのかを意識しないとはまる

- scala.html の素の部分はそのまま HTML として出力される
- @ で始まる構文は play の 構文
- 1行目はその HTML のクラスに渡される args とみなされる
- @で始まる部分は scala の領域~
ただし、どこまでが、scala かがわかりにくい
- {} で囲まれている部分は Html という型(クラス)のインスタンスとなる
- @ で始まるものは 変数だったり scala のファンクションだったり、いろいろ

*** 変数宣言方法 [#w6e2afa7]
 @i = @{1}
 @s = @{"string"}
 @h = {<h1>hoge</h1>}

java 的に翻訳すると
 final int i = 1;
 final String s = "string";
 final play.api.templates.Html h = new Html("<h1>hoge</h1>");
final なので二度と書き換えられない点にも注意

ちなみに HTML 型の中( {} ) 中は、@hogehoge で変数を展開できる


//------------------------------------
* デザイン (bootstrap3 の使い方) [#w6bbd498]
play2 にはデフォのサンプルとして、samples/java/computer-database というものがあるが、bootstrap2 なので若干古い。~
3を充てるための手順~

まず bootswatch でお好みデザインを選ぶ( Themes v でいろいろ選べる )
 http://bootswatch.com/cosmo/
bootswatch-xxxx のところにテーマ名を入れる

''build.sbt''
 (略)
  "org.webjars" %% "webjars-play" % "2.2.2-1",
  "org.webjars" % "bootswatch-flatly" % "3.2.0-1",
  "org.webjars" % "jquery" % "1.11.1",
 (略)
 
 resolvers += "webjars" at "http://webjars.github.com/m2"

'' sticky - footer ''
 cd public/stylesheets
 wget "http://getbootstrap.com/examples/sticky-footer-navbar/sticky-footer-navbar.css"

''conf/routes''
 GET     /webjars/*file              controllers.WebJarAssets.at(file)

''views/layout/main.scala.html''
 @(title: String)(content: Html)
 
 <!DOCTYPE html> 
 
  <html>
    <head>
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@routes.WebJarAssets.at(WebJarAssets.locate("bootswatch" , "bootstrap.min.css"))">
		<script type='text/javascript' src='@routes.WebJarAssets.at(WebJarAssets.locate("jquery.min.js"))'></script>
		<meta name='viewport' content='width=device-width , initial-scale = 1.0'>
        <link rel='stylesheet' media='screen' href='@routes.Assets.at("stylesheets/main.css")'>
        <link rel='shortcut icon' type='image/png' href='@routes.Assets.at("images/favicon.png")'>
        <link href="@routes.Assets.at("stylesheets/sticky-footer-navbar.css")" rel="stylesheet">
        <link href="@routes.Assets.at("stylesheets/bootswatch.min.css")" rel="stylesheet">
    </head>
    <body>
    	@tag.menu()
		@tag.flashMessage()
		<div class="container">
			<div id="banner" class="page-header">
        	</div>
			<div class="clearfix">
	    		@content
   			</div>
    	</div>
        @tag.footer()
    </body>
 </html>

''index2.scala.html''
 @(message: String)
 
 @layout.main("Welcome to Play") { 
 <div class="panel panel-primary">
  <div class="panel-heading">
    <h3 class="panel-title">Panel primary</h3>
  </div>
  <div class="panel-body">
    Panel content
  </div>
 </div> 
 
 <div class="panel panel-success">
  <div class="panel-heading">
    <h3 class="panel-title">Panel success</h3>
  </div>
  <div class="panel-body">
    Panel content
  </div>
 </div> 
 
 <div class="panel panel-info">
  <div class="panel-heading">
    <h3 class="panel-title">Panel info</h3>
  </div>
  <div class="panel-body">
    Panel content
  </div>
 </div>
 @*
 <div class="panel panel-warning">
  <div class="panel-heading">
    <h3 class="panel-title">Panel warning</h3>
  </div>
  <div class="panel-body">
    Panel content
  </div>
 </div>
 
 <div class="panel panel-danger">
  <div class="panel-heading">
    <h3 class="panel-title">Panel danger</h3>
  </div>
  <div class="panel-body">
    Panel content
  </div>
 </div>
 *@
 <table class="table table-striped table-hover">
  @for(i <- 1 to 10){
  	<tr><td>@i</td></tr>
  }
  </table>
 }

 cd public/stylesheets
 wget http://bootswatch.com/assets/css/bootswatch.min.css

//------------------
* CSRF [#g0410cf1]
基本的に form で POST したり GET でも引数に値を入れて副作用を起こすものには導入すること~
[[play2/csrf]]

//----------------
* トラブルシューティング[#y2132d6e]
フレームワークはお作法を間違えるととにかくトラブル

*** play eclipse [#x36f91cb]
 [message]  Error evaluating task 'dependencyClasspath': error
 [message] FATAL ERROR in native method: JDWP No transports initialized,           
 [原因] play がすでに起動していてファイルに書き込めない
 [対処] java.exe を殺す (タスクマネージャ / pkill など)

*** JUnit [#o8a9b5d8]
 [message] enhanced 
 [原因] eclipse 上 ebean の enhanced コンパイルが行われていない
 [対処] ebean2 のプラグインを入れ [enhanced ] をオンにする

*** JUnit [#xe1d99b3]
 [message] Unsupported major.minor version 
 [原因] JUnit が実行する java runtime があっていない
 [対処] プロジェクト右クリック -> 実行/デバッグ で JRE を合わせる
        それでもダメなら play clean ; play compile ; play eclipse ; play test

** Scala template[#x23af31f]
*** スペース重要 [#gcc03c7e]
 × @if ( hoge == "1" )

 ○ @if(hoge=="1")
※知らないとやり場のない怒りが・・

*** 変数宣言 [#oae11f2f]
 @a = @{1}
 @b = @{"abc"}
 @c = {<html>hoge</html>}

*** ローカル変数 [#u1ba5e8f]
#pre{{
 @for(i <- list){ 
   @defining( i * 2 ){ j =>
      i の 2倍は @j
   }
 }
}}
forブロック内でのローカル変数作るだけでこんなに大変

*** continue がない [#yeabd7fd]
#pre{{
  @hasMan = @{
     for(i <- userlist){
        var result = false
        if (i.gender == "man"){
             result = true
        }
        result
     }
  }
}}
* H2 DB でがんばろう [#r7b20f4d]
''とりあえず select とか insert とか delete とかjava のプログラムなしでやりたいじゃん!''

''application.conf''
#pre{{
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:file:play;AUTO_SERVER=TRUE;MODE=MYSQL;"
db.default.user=sa
db.default.password=""
applyEvolutions.default=true
}}

 cd c:/play2/workspace/hoge
 play run

 cd c:/play2/workspace/hoge
 java -Dfile.encoding=UTF8 -cp `find c:/play2 -name h2.jar` org.h2.tools.Shell -url "jdbc:h2:file:play;AUTO_SERVER=TRUE;MODE=MYSQL;" -user sa

* template から [#z1f5adf0] 
** 初期状態で eclipse に取り込む [#s9e4fb1d]
 cd c:/play2/workspace
 play new hoge
 cd hoge
 play eclipse 

- eclipse で取込み

** 設定ファイルの取得 [#tb92532e]
''build.sbt''

 import com.github.play2war.plugin._
 
  filters,
 "commons-io" % "commons-io" % "2.4",
 "org.seleniumhq.selenium" % "selenium-server" % "2.42.2" % "test",
 "org.webjars" %% "webjars-play" % "2.2.2-1",
 "org.webjars" % "bootswatch-cerulean" % "3.2.0",
 "org.webjars" % "jquery" % "1.11.1",
 
 resolvers += "webjars" at "http://webjars.github.com/m2"
 
 Play2WarPlugin.play2WarSettings
 
 Play2WarKeys.servletVersion := "3.0"

''conf/application.conf''
 db.default.driver=org.h2.Driver
 db.default.url="jdbc:h2:file:play;AUTO_SERVER=TRUE;MODE=MYSQL;"
 db.default.user=sa
 db.default.password=""
 ebean.default="models.*"

''project/plugins.sbt''
 addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.5.0")
 
 addSbtPlugin("com.github.play2war" % "play2-war-plugin" % "1.2")
 

** 一旦再構築 [#q98ba03d]
 play "eclipse with-source=true with-javadoc=true"

- eclipse のパッケージエクスプローラーで F5

** util系統のファイルコピー [#s2de9b04]

 app/Global.java
 app/models/Item.java
 app/controllers/Items.java
 app/util
 app/views/helper
 app/views/item
 app/views/index.scala.html
 app/views/main.scala.html
 public/stylesheets

''routes''
#pre{{
GET     /webjars/*file              controllers.WebJarAssets.at(file)

# Base CRUD (for each model)
GET    /item                       controllers.Items.index(page:Int ?= 1, perPage:Int ?=10, sortBy:String ?= "updatedAt", orderBy:String ?= "desc" , filterKey:String ?= "", filterValue:String?="")
GET    /item/create                controllers.Items.createForm()
POST   /item/create                controllers.Items.create()
GET    /item/:id                   controllers.Items.read(id:Long)
GET    /item/update/:id            controllers.Items.updateForm(id:Long)
POST   /item/update/:id            controllers.Items.update(id:Long)
GET    /item/delete/:id            controllers.Items.delete(id:Long)
}}

- model の方の ファイル名を refectering して bean を作る
- controller の bean の名前を rename する
- controller の import を合わせる
- test/ApplicationTest.java の renderTemplate() をコメントアウトする

* deploy 方法 [#jfde64e3]
 play war 

で、 target/xxxx.war が作成されるので jetty/webapps の下に配置する

* code [#d5cd8e9f]
*** raw sql [#b11ede5d]
#pre{{
String sql = "select holiday.id, user.id, country.id"
  + " from holiday "
  + " join country on country.id=country_id "
  + " join user    on user.uid=holiday.uid ";
RawSql rawSql = RawSqlBuilder.parse(sql)
				.columnMapping("user.id", "user.id")
				.create();
return Ebean.find(Holiday.class).setRawSql(rawSql).findList();
}}


*** fetch (join して一気にもってきたい場合 ) [#h2083671]
#pre{{
  return Ebean.find(Holiday.class).fetch("country").findList();
}}