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?
Advertisement
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 }); } }