4

PlayFrameworkのscalaqueryに「リクエストベース」のセッションを実装しようとしています。次のように、scalaqueryを使用してセッションを作成し、現在のhttpコンテキストに保存しようとします。

def withTransaction[A](bp: BodyParser[A])(f: Request[A] => Result): Action[A] = {
   Action(bp) {
     request =>
       val context = Http.Context.current()
       val session = createSession()
       session.conn.setAutoCommit(false)
       context.args.put("scalaquery.session", session)
       try {
         val result = f(request)
         session.conn.commit()
         result
       }
       catch {
         case t: Throwable =>
           session.conn.rollback()
           throw t
       }
       finally {
         session.close()
         context.args.remove("scalaquery.session")
       }
   }
}

次に、次のようにアクションをコントローラーにラップします。

withTransaction(parse.anyContent) {
    Action {
       //code that produces a result here
    }
}

ただし、次の行でクラッシュします。

val context = Http.Context.current() 
[RuntimeException: There is no HTTP Context available from here.] 

では、なぜコンテキストが利用できないのですか?このコードはフレームワークによって直接呼び出されるので、このコードが実行されるまでにコンテキストを設定するべきではありませんか?または、コンテキストにアクセスするために間違った方法を使用していますか?

編集:「セッション」のタイプはorg.scalaquery.session.Sessionです。HttpContextに設定する理由は、ラップされたアクションが「httpスコープ」の方法でアクセスできるようにするためです。つまり、各リクエストはセッションを個別に保存しますが、セッションを必要とするすべてのサービスはパブリックでそれを見つけることができます。リクエストごとに分離されたスコープ。

4

1 に答える 1

1

問題は、Scala コントローラーで Java API を使用していることだと思います。Http.ContextJava コントローラーを使用している場合にのみ設定されます。Scala Session APIの使用を検討しましたか?

また、別の質問は、なぜセッションをコンテキストに保存する必要があるのですか? とにかく最後にそれを削除するだけです。サブアクションがセッションにアクセスできるようにすることが必要な場合は、それを関数に渡すことができます。

私はちょうどsessionタイプのものであると仮定するつもりですSession

def withTransaction[A](bp: BodyParser[A])(f: Session => Request[A] => Result): Action[A] = {
   Action(bp) {
     request =>
       val session = createSession()
       session.conn.setAutoCommit(false)
       try {
         val result = f(session)(request)
         session.conn.commit()
         result
       }
       catch {
         case t: Throwable =>
           session.conn.rollback()
           throw t
       }
       finally {
         session.close()
       }
   }
}

そしてあなたのサブアクションは

withTransaction(parse.anyContent) { session => request =>
    //code that produces a result here
}

Actionすでにラップされているため、これをラップする必要はありませんwithTransaction

于 2012-08-12T03:16:48.827 に答える