我有一个基于Play框架和Scala构建的Web应用程序。它是关于向用户呈现一组问题,每个问题都有一组答案。有些问题的单选按钮类型有答案,有些有复选框作为答案。当用户单击开始测试时,我调用控制器,获取问题列表及其答案,并将结果作为案例类返回到视图模板。我现在需要在用户回答每个问题时保持测试状态。他可以前一个,下一个,我需要跟踪他回答的所有问题。
来自Java EE背景,我想我可以在会话中存储case类并在我的控制器中操作它。但遗憾的是,由于Play框架的会话是一个String,String而不是String,Object的键值对,所以看起来并不像那样。我现在坚持使用我的应用程序,因为我对Play框架的体验有限,我想征求意见。
答案 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)