播放框架处理会话状态

时间:2013-12-25 12:34:53

标签: scala session playframework-2.1

我有一个基于Play框架和Scala构建的Web应用程序。它是关于向用户呈现一组问题,每个问题都有一组答案。有些问题的单选按钮类型有答案,有些有复选框作为答案。当用户单击开始测试时,我调用控制器,获取问题列表及其答案,并将结果作为案例类返回到视图模板。我现在需要在用户回答每个问题时保持测试状态。他可以前一个,下一个,我需要跟踪他回答的所有问题。

来自Java EE背景,我想我可以在会话中存储case类并在我的控制器中操作它。但遗憾的是,由于Play框架的会话是一个String,String而不是String,Object的键值对,所以看起来并不像那样。我现在坚持使用我的应用程序,因为我对Play框架的体验有限,我想征求意见。

3 个答案:

答案 0 :(得分:11)

在Play框架中根本没有任何状态,所以如果你想在多个HTTP请求中保留一些数据,那么使用会话范围实际创建带有键/值对(String,String)的cookie并且限制为4KB大小

我的建议是用Json做,Play-json库真棒。如果您的模型使用JSON Read/Write/Format组合器而非简单组合。

Ok(render(Questions)).withSession("answers" -> Json.prettyPrint(Json.toJson(Answer)))

读取会话值可以这样做:

def index = Action { implicit request =>
      session.get("answers").map { answers =>
        val jsValueAnswers: JsValue = Json.parse(answers)
        val answersModel: YourAnswerModel = Json.fromJson(jsValueAnswers) 
        Ok("Got previous answers and created session cookie with them")
        .withSession("answers2" -> Json.prettyPrint(Json.toJson(answersModel)))
      }
    }

希望这对你有所帮助。

干杯

答案 1 :(得分:8)

Play仅支持会话字符串,因为它将所有会话状态存储在Cookie中 - 这意味着Play节点可以扩展而无需任何类型的群集/状态共享技术。

如果您要存储的数据很小(小于2k),那么只需将其序列化为JSON,或者听起来就像您的情况一样,更简单的是将其序列化为逗号分隔的答案列表。

否则,您可以将其存储在缓存中,例如memcached或redis。

答案 2 :(得分:3)

Play是一个设计为无状态的框架,因此您找不到服务器端会话的任何具体概念。当然,如果您需要,这并不是严格禁止的,因为在这种情况下,您可以使用服务器端技术(缓存或数据库)作为项目的容器,并使用Play-cookie会话来存储访问密钥字符串。

这是使用Play Cache存储对象的示例:

import play.api.cache.Cache
import play.api.Play.current

val key = UUID.randomUUID.toString
Cache.set(key, yourModel, 0)
Ok.withSession("answer_key" -> key)

这是一个检索的例子:

import play.api.cache.Cache
import play.api.Play.current

val key = session.get("answer_key").getOrElse("none")
val yourModel = Cache.getAs[ModelClass](key).getOrElse(//whatever you want if not exists)