Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Play framework 2.0: хранить значения в Http.Context

Автор вопроса: Angel BlancoОтветов: 1

Я пытаюсь реализовать сеансы "на основе запросов" в scalquery в игровой среде. Я создаю сеанс с помощью 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-scoped", т.е. чтобы каждый запрос хранил свой сеанс отдельно, но все службы, которым нужен сеанс, могут найти его в общедоступном область, которая отделяется для каждого запроса.

scalahttpcontextplayframework

Ответы

Ответ 1 · рейтинг 1 · thatsmydoing

Я думаю, проблема в том, что вы используете Java API с контроллером Scala. Http.Context устанавливается, только если вы используете контроллер Java. Рассматривали ли вы возможность использования 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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы