从 Constraints.ValidationPayload 获取 TypedMap 的值

Get value of TypedMap from Constraints.ValidationPayload

我们将 playframework 2.8 与 java 一起使用,并使用 DI 和有效负载实现了表单验证,如官方游戏文档中所述 https://www.playframework.com/documentation/2.8.x/JavaForms#Custom-class-level-constraints-with-DI-support

有效负载对象使用 getAttr() 方法提供包含请求属性的 TypedMap。这由 this documentation

解释

由于 TypedKey 的实例用于存储映射中的值,我们无法访问框架本身存储的任何请求属性。可以在 Github and in this Whosebug post

上找到更多详细信息

似乎无法从 TypedMap 中获取所有现有键。
所以,问题是:当我们没有 TypedKey 的实例时,我们如何获取 Play 已经存储的 TypedMap 的值?

Request.attrs TypedMap 的键存储在 play.api.mvc.request.RequestAttrKey 对象中:

package play.api.mvc.request

import ...

/**
 * Keys to request attributes.
 */
object RequestAttrKey {

  /**
   * The key for the request attribute storing a request id.
   */
  val Id = TypedKey[Long]("Id")

  /**
   * The key for the request attribute storing a [[Cell]] with
   * [[play.api.mvc.Cookies]] in it.
   */
  val Cookies = TypedKey[Cell[Cookies]]("Cookies")

  /**
   * The key for the request attribute storing a [[Cell]] with
   * the [[play.api.mvc.Session]] cookie in it.
   */
  val Session = TypedKey[Cell[Session]]("Session")

  /**
   * The key for the request attribute storing a [[Cell]] with
   * the [[play.api.mvc.Flash]] cookie in it.
   */
  val Flash = TypedKey[Cell[Flash]]("Flash")

  /**
   * The key for the request attribute storing the server name.
   */
  val Server = TypedKey[String]("Server-Name")

  /**
   * The CSP nonce key.
   */
  val CSPNonce: TypedKey[String] = TypedKey("CSP-Nonce")
}

那些是 Scala 键。这不是什么大问题,java TypedMap 只是 scala TypedMap 的包装器。

来自 java 的示例用法,当我们有 Http.Request:


import scala.compat.java8.OptionConverters;
import play.api.mvc.request.RequestAttrKey;

class SomeController extends Controller {

    public Result index(Http.Request request) {

        //get request attrs  
        play.libs.typedmap.TypedMap javaAttrs = request.attrs();

        //get underlying scala TypedMap
        play.api.libs.typedmap.TypedMap attrs = javaAttrs.asScala();

        //e.g. get Session from scala attrs
        Optional<Cell<Session>> session = 
            OptionConverters.toJava(attrs.get(RequestAttrKey.Session()));

        //process session data
        session.ifPresent(sessionCell -> {
            Map<String, String> sessionsData = sessionCell.value().asJava().data();

        //do something with session data
        });
    }
}