Play2.2(Java)†
play2を java で windows で eclipse で開発する方法
インストール†
install は便宜上 c:\ に行っているが、"Program Files"など スペースが入っていないところが望ましい
eclipse†
play 用の java の記述は癖があるので、新規に入れた方が良い
play2/eclipse
java†
play は eclipse と コマンドラインの双方でコンパイルすることになる
それらのバージョンが違っていると無駄にはまるので注意
OS の環境設定で下記を追加
JAVA_HOME | c:\java\jdk1.8.0_40 |
PATH | c:\java\jdk1.8.0_40\bin |
> java -version
> javac -version
でバージョンを確認
play2†
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 の環境変数設定で下記を追加
play プロジェクト作成†
play2/HelloPlay
eclipse に取り込み†
play2/eclipsify
MVC と ORM のサンプルプログラム†
play2/sample
バージョン管理†
- とりあえず svn
- SVN にあげてはいけないもの (ignore の設定)
logs |
project/project |
project/target |
target |
tmp |
.history |
dist |
/.idea |
/*.iml |
/out |
/.idea_modules |
/.classpath |
/.project |
/RUNNING_PID |
/.settings |
sbt†
- 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 でソースコードの参照もできる)
テスト†
play2/test
scala.html†
はっきりいって play で初めて scala に触れた Java プログラマにはさっぱり理解できない
どこまでが scala 部分で、どこからが play の構文なのかを意識しないとはまる
- scala.html の素の部分はそのまま HTML として出力される
- @ で始まる構文は play の 構文
- 1行目はその HTML のクラスに渡される args とみなされる
- @で始まる部分は scala の領域
ただし、どこまでが、scala かがわかりにくい
- {} で囲まれている部分は Html という型(クラス)のインスタンスとなる
- @ で始まるものは 変数だったり scala のファンクションだったり、いろいろ
変数宣言方法†
@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 の使い方)†
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†
基本的に form で POST したり GET でも引数に値を入れて副作用を起こすものには導入すること
play2/csrf
トラブルシューティング†
フレームワークはお作法を間違えるととにかくトラブル
play eclipse†
[message] Error evaluating task 'dependencyClasspath': error
[message] FATAL ERROR in native method: JDWP No transports initialized,
[原因] play がすでに起動していてファイルに書き込めない
[対処] java.exe を殺す (タスクマネージャ / pkill など)
JUnit†
[message] enhanced
[原因] eclipse 上 ebean の enhanced コンパイルが行われていない
[対処] ebean2 のプラグインを入れ [enhanced ] をオンにする
JUnit†
[message] Unsupported major.minor version
[原因] JUnit が実行する java runtime があっていない
[対処] プロジェクト右クリック -> 実行/デバッグ で JRE を合わせる
それでもダメなら play clean ; play compile ; play eclipse ; play test
Scala template†
スペース重要†
× @if ( hoge == "1" )
○ @if(hoge=="1")
※知らないとやり場のない怒りが・・
変数宣言†
@a = @{1}
@b = @{"abc"}
@c = {<html>hoge</html>}
ローカル変数†
@for(i <- list){
@defining( i * 2 ){ j =>
i の 2倍は @j
}
}
forブロック内でのローカル変数作るだけでこんなに大変
continue がない†
@hasMan = @{
for(i <- userlist){
var result = false
if (i.gender == "man"){
result = true
}
result
}
}
H2 DB でがんばろう†
とりあえず select とか insert とか delete とかjava のプログラムなしでやりたいじゃん!
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=""
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 から†
初期状態で eclipse に取り込む†
cd c:/play2/workspace
play new hoge
cd hoge
play eclipse
設定ファイルの取得†
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")
一旦再構築†
play "eclipse with-source=true with-javadoc=true"
- eclipse のパッケージエクスプローラーで F5
util系統のファイルコピー†
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
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 方法†
play war
で、 target/xxxx.war が作成されるので jetty/webapps の下に配置する
code†
raw sql†
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 して一気にもってきたい場合 )†
return Ebean.find(Holiday.class).fetch("country").findList();