scalaなんて知らない。
Javaでplay frameworkをゴリゴリ書いていきたい。
いろいろハマったので書いておく。
インストール(Mac/要brew)
-
brew install play
play 2.2までしか入らない。2.3以降使いたい場合は下記参照。 -
brew install typesafe-activator
play 2.3よりactivator使う様になったらしい。
アップデート(Mac/要brew)
brew upgrade typesafe-activator
で Error: typesafe-activator 1.3.2 already installed
とエラーが出る場合。
brew update
をかけて、アップデートしたのち、brew upgrade typesafe-activator
を行う。
コマンドについて(2.2からの違い)
$play run
とかやってたけど、 $activator run
とかやればいい。
様は、play
を activator
にしてやれば上手く行く。
対応が無いコマンドとかはよく知らない。調べてない。ざっと使った感じ問題なさそう。
外部ライブラリを追加する(SBT)
build.sbt に追記していくっぽい。
libraryDependencies ++= Seq( ) の中にいろいろと書いていく。
name := "YourFirstApp"
version := "1.0-SNAPSHOT"
libraryDependencies ++= Seq(
javaJdbc,
javaEbean,
cache,
filters, //追加
"org.jongo" % "jongo" % "1.0", // 追加
"org.mongodb" % "mongo-java-driver" % "2.11.4" // 追加
)
play.Project.playJavaSettings
※ 2.3になってちょっとかわったけどlibraryDependencies
に追加していくのはかわらないので、体勢に影響は無い。
SBT(Scala Build Tool?)の形式ってよくわからない。
-
http://mvnrepository.com/に
のサイトで検索して、SBTのタブがあるので便利 - Googleで「XXXXX maven」(XXXXはライブラリ名)と検索して、http://mvnrepository.com/サイトのSBTのタブを見ればOK。
※ SBTあたりはもうちょいリサーチしたい。
Eclipseプロジェクト周りでハマること
v2.4
からはeclipse
コマンドが使えない
eclipse はデフォルトでは使えない・・・
解決策
eclipse淘汰が始まってる・・・。
- IntelliJ IDEAの場合は、scala pluginを入れた後、playのアプリプロジェクトフォルダをimport先に指定すれば動く。
- eclipseは今まで通り。
eclipse with-source=true
の後のプロジェクトのインポート時
- 「プロジェクトをワークスペースにコピー」のチェックボックスを外すことは絶対忘れない。
※ 以前、eclipsify
だったけどどっかのバージョンでeclipse
に変わったらしい。
build.sbtを更新したとき(ライブラリ追加した際)
update
eclipse with-source=true
- プロジェクトをリフレッシュ(F5更新)
※コンパイルエラーがある場合は、compile通る様にしておくこと。eclipse with-source=true
のコンパイルでこけて、更新されない。
※ update
を打ってもSBTの更新が反映されない時。reload
コマンドを打った後、update
を打つと解決することがあった。(2014/11/29現在)
Play Frameworkの書き方とか
RESTfulなAPIを作りたくてハマったこと
たぶん、いろいろやり方はあるんだろうけども、とりあえず、これで動いたという事で。
js側コード
$.ajax({
url: '/hogehoge/',
data : typeof data == "string"?data:JSON.stringify(data || {}),
cache : false,
type: type,
dataType: 'json',
success: function(data){ console.log(data)},
error : function(){ console.log('error!')},
contentType : "application/json; charset=utf-8"
});
play側コード(Controller)
GET /hogehoge/ controllers.Application.getHoge()
// 略
public static Result getHoge(){
JsonNode json = request().body().asJson();
// だめだった場合の返し方。正しいのか不明だけども。
if(hasError()){ //hasErrorは適当です。
return badRequest(Json.toJson("ng"));
}
// Json.toJson メソッドを用いて、オブジェクトでもMapでもなんでも返せるので便利。
return ok(Json.toJson("ok"));
}
// 略
Formの使い方っぽいこと?
※ play.data.Form のこと
HTMLからの入力をJsonで受け取るとして、パラメータから受け取ったりしてばらしたりとか、validationとか色々面倒。
そこで、Formを用いれば楽になるっぽい。
JavaForm(Official)
package hoge;
import play.data.validation.Constraints.Pattern;
import play.data.validation.Constraints.Required;
public class SampleForm {
@Required(message="必須入力です") //エラー時のメッセージも入力できる
public String sample1;
@Required
@Pattern(value="\\d{4}/\\d{2}/\\d{2}", message="形式に合わせて入力してね!") // YYYY/MM/dd の形式にマッチさせる
public String startDate;
@Required
@Pattern(value="\\d{4}/\\d{2}/\\d{2}") // YYYY/MM/dd の形式にマッチさせる
public String endDate;
public String validate(){
Date startDate_ = convertString2Date(startDate);
Date endDate_ = convertString2Date(endDate);
if(startDate_.compareTo(endDate_)>0){
return "終了日より開始日が前になっています。";
}else{
return null; // 正常時はnullを返す仕様らしい
}
}
}
// 略
public static Result getHoge(){
JsonNode json = request().body().asJson();
Form<SampleForm> form = Form.form(SampleForm.class).bind(json);
if(form.hasErrors()){ // SampleFormクラスのvalidate()メソッドも同時に呼ばれるみたい。ソースコードは読んでない。
return badRequest(form.errorsAsJson());
}else{
SampleForm sampleForm = form.get();
Logger.debug(sampleForm.sample1);
return ok(Json.toJson("ok"));
}
}
// 略
他のValidator
- Constraints.Email - メールアドレス
- Constraints.Max - 最大値
- Constraints.MaxLength - 最大サイズ
- Constraints.Min - 最小値
- Constraints.MinLength - 最少サイズ
- Constraints.Pattern - 正規表現
- Constraints.Required - 必須
- Constraints.ValidateWith - 他との組み合わせ?(使ったことない)、参考になりそうなStackOverFlowのリンク
xxxx.scala.html について
controllerからviewにアサインする時に、名前解決ができなくてコンパイルエラーになる場合がある。その場合、フルパス(例:input.form.SomethingForm)で書くとエラーが解消される。@import input_
だとエラーのままだった。
@(aaaa : Form[input.form.SomethingForm])
CSRF対策について
CSRF対策のトークンを入れるまで(ソース)
- build.sbt の依存関係に
filters
を追加する。 - CSRF filter用のクラスを作成する
import play.GlobalSettings;
import play.api.mvc.EssentialFilter;
import play.filters.csrf.CSRFFilter;
public class Global extends GlobalSettings {
@Override
public <T extends EssentialFilter> Class<T>[] filters() {
return new Class[]{CSRFFilter.class};
}
}
- ControllerにCSRF用追加する箇所と検証する箇所にアノテーションを入れる
@play.filters.csrf.AddCSRFToke
public static Result get(){
//.. something
}
@play.filters.csrf.RequireCSRFCheck
public static Result save() {
//.. something
}
- Viewの
@Form
内に書き込む
@form(routes.HogeController.save()) {
@CSRF.formField
...
}
or
@import helper._
@form(CSRF(routes.HogeController.save())) {
...
}