Hatena::ブログ(Diary)

すにぺっと

2011-04-19

play-scalaを改めて学ぶ-5 Scalaで書くPlayのコントローラーその2

| 10:42 | play-scalaを改めて学ぶ-5 Scalaで書くPlayのコントローラーその2を含むブックマーク

http://scala.playframework.org/documentation/scala-0.9/controllers

のplay-scalaコントローラーの続き。

このあたりは単純に定義されたHTTPステータスを返す。

Created

HTTPステータス201を返す。

def index = Created

Accepted

HTTPステータス202を返す。

def index = Accepted

NoContent

HTTPステータス204を返す。

def index = NoContent

Action

アクションメソッドが値を返す場合、適切なURLを解決するために

アクションメソッド引数を使用して、

対応するアクションへブラウザリダイレクトする。

def index = Action(show(3))

「show(3)」は、by-nameパラメータで、対応するメソッドは呼び出されていない。

playは、URL(users/3とか)として、この呼び出しが解決されるとそのURLリダイレクトされる。

また、アクションは、新しいリクエストのコンテキストで呼び出される。


Javaコントローラでは、対応するアクションメソッド

直接呼び出すことによって同じ結果を達成している。

Scalaを使用した場合はcall by nameコンセプトを使用し、

コンパイラチェックによって型保証された

リダイレクトを維持することができる。

・・・ScalaのはJavaとは別の仕組みでうまくタイプセーフな

呼び出しができてるってこと?


Redirect

HTTPステータス301を返す。

def index = Redirect("http://www.google.com")

また、第2引数を指定すれば、ステータスコード

301と302を切り替えられる。

//HTTP STATUS CODE 302
def index = Redirect("http://www.google.com", false)

NotModified

HTTPステータス304を返す。

def index = NotModified

また、ETagのレスポンスも返すことができる。

なんだETagって??

def index = NotModified("123456")

BadRequest

HTTPステータス400を返す。

def index = BadRequest

Unauthorized

HTTPステータス401を返す。

def index = Unauthorized

realm nameも指定できますよ、と。

def index = Unauthorized("Administration area")

Forbidden

HTTPステータス403を返す。

def index = Forbidden

エラーメッセージを付けることも可能。

def index = Forbidden("Unsufficient permissions")

NotFound

HTTPステータス404を返す。

def index = NotFound

リソース名を指定したり、

任意のパスへ飛ばしたりできる。

def index = NotFound("Article not found")
def index = NotFound("GET", "/toto")

Error

HTTPステータス500を返す。

def index = Error

エラーメッセージをつけたり、コードをつけたりできる。

def index = Error("Oops…")
def index = Error(503, "Not ready yet…")

Return type inference

アクションメソッド戻り値として、いろいろな戻り値が使用できる。

例えばString

def index = "<h1>Hello world</h1>"

またはビルトインでサポートされているXML形式

def index = <h1>Hello world</h1>

戻り値バイナリのような場合、

playが自動でバイナリとしてレスポンスをレンダリングする。

組み込みのCaptcha helperを使用してcaptcha imageを生成する場合。

def index = Images.captcha

Controller interceptors

Controllerのインターセプターについては、ほぼJavaと同じように動く。

通常と同じく、クラスやメソッドアノテーションをつければOK.

@Before def logRequests {
    println("New request…")
}

このlogRequestsメソッドは、何も値を返さない。

そのため、requestは次のインターセプター(最終的にはアクションメソッド

を呼び出すことによって継続される。

また、値を返すインターセプターを記述することもできる。

@Before def protectActions = {
    Forbidden
}

ここで実行が停止し、Forbiddenの値が生成される。

処理を継続するには、「Continue」を返す必要がある。

@Before def protectActions = {
    session("isAdmin") match {
        case Some("yes") => Continue
        case _ => Forbidden("Restricted to administrators")
    }
}

Mixing controllers using Traits

Scalaのトレイトは、いくつかのアスペクトを統合することにより、

効率的にコントローラーを作成できる。

トレイトもコントローラーと同じようにインターセプターとアクションメソッド

を定義可能。

例として、Secureトレイトでseucrityチェックのインターセプターを定義し、

コントローラーにmix-inする。

trait Secure {
    self:Controller =>
    
    @Before checkSecurity = {
        session("username") match {
            case Some(username) => renderArgs += "user" -> User(username)
                                   Continue
            case None => Action(Authentication.login)
        }
    }
    
    def connectedUser = renderArgs("user").get
    
}

「self:Controller =>」の記法を使うと、このトレイトが

コントローラーにmix-inできることを示す。

(あってる??)

そして、Secureトレイトをmix-inしたコントローラーを定義。

object Application extends Controller with Secure {
    
    def index = <h1>Hello {connectedUser.name}!</h1>
    
}

翻訳してもよくわからーん。

次はHTTP to Scala data bindingの巻。


プログラミングScala
プログラミングScala
posted with amazlet at 11.04.19
Dean Wampler Alex Payne
オライリージャパン
売り上げランキング: 24883

RIREXRIREX 2014/12/18 12:20 今更ですが本当に助かりました!ありがとうございます。

トラックバック - http://d.hatena.ne.jp/sy-2010/20110419/1303177338
Connection: close