LoginSignup
71
74

More than 5 years have passed since last update.

はじめてのPlay Frameworkで詰まった事のメモ

Last updated at Posted at 2014-03-18

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 とかやればいい。
様は、playactivatorにしてやれば上手く行く。
対応が無いコマンドとかはよく知らない。調べてない。ざっと使った感じ問題なさそう。

外部ライブラリを追加する(SBT)

build.sbt に追記していくっぽい。
libraryDependencies ++= Seq( ) の中にいろいろと書いていく。

build.sbt
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?)の形式ってよくわからない。

※ SBTあたりはもうちょいリサーチしたい。

Eclipseプロジェクト周りでハマること

v2.4からはeclipseコマンドが使えない

eclipse はデフォルトでは使えない・・・

解決策
1. eclipseを諦めて、IntelliJ IDEAにscala pluginを入れる。(参照
2. eclipseで動かすには、sbteclipse を入れる。(参照

eclipse淘汰が始まってる・・・。

  1. IntelliJ IDEAの場合は、scala pluginを入れた後、playのアプリプロジェクトフォルダをimport先に指定すれば動く。
  2. eclipseは今まで通り。

eclipse with-source=trueの後のプロジェクトのインポート時

  1. 「プロジェクトをワークスペースにコピー」のチェックボックスを外すことは絶対忘れない。

※ 以前、eclipsifyだったけどどっかのバージョンでeclipseに変わったらしい。

build.sbtを更新したとき(ライブラリ追加した際)

  1. update
  2. eclipse with-source=true
  3. プロジェクトをリフレッシュ(F5更新)

※コンパイルエラーがある場合は、compile通る様にしておくこと。eclipse with-source=trueのコンパイルでこけて、更新されない。
※ updateを打ってもSBTの更新が反映されない時。reloadコマンドを打った後、updateを打つと解決することがあった。(2014/11/29現在)

Play Frameworkの書き方とか

RESTfulなAPIを作りたくてハマったこと

たぶん、いろいろやり方はあるんだろうけども、とりあえず、これで動いたという事で。

js側コード

get.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)

routes
GET  /hogehoge/ controllers.Application.getHoge()
Application.java

// 略
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)

SampleForm.java

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を返す仕様らしい
      }
    }
}

Application.java

// 略
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_だとエラーのままだった。

xxxx.scala.html
@(aaaa : Form[input.form.SomethingForm])

CSRF対策について

CSRF対策のトークンを入れるまで(ソース

  • build.sbt の依存関係にfilters を追加する。
  • CSRF filter用のクラスを作成する
Global.java
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用追加する箇所と検証する箇所にアノテーションを入れる
HogeController.java

@play.filters.csrf.AddCSRFToke
public static Result get(){
  //.. something
}

@play.filters.csrf.RequireCSRFCheck
public static Result save() {
    //.. something
}
  • Viewの @Form 内に書き込む
some.scala.html
@form(routes.HogeController.save()) {
    @CSRF.formField
    ...
}

or

some.scala.html
@import helper._

@form(CSRF(routes.HogeController.save())) {
    ...
}
71
74
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
71
74