Get value of TypedMap from Constraints.ValidationPayload

Tags: , ,



We’re using playframework 2.8 with java and have implemented a form validation using DI and a payload as explained in the official play documentation https://www.playframework.com/documentation/2.8.x/JavaForms#Custom-class-level-constraints-with-DI-support

The payload object provides a TypedMap containing attributes from the request, using the getAttr() method. This is explained by this documentation

Since the instance of a TypedKey is used to store the value in the map, we’re not able to access any request attributes, stored by the framework itself. More details can be found on Github and in this Stackoverflow post

It seems, it’s not possible to fetch all existing keys from a TypedMap.
So, the question is: How can we get values of the TypedMap, which were already stored by play, when we don’t have the instance of the TypedKey?

Answer

Keys for Request.attrs TypedMap are stored inside play.api.mvc.request.RequestAttrKey object:

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")
}

Those are scala keys. This is not big problem, java TypedMap is just wrapper for scala TypedMap.

Example usage from java, when we have 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
        });
    }
}



Source: stackoverflow