[Play 2.4.3-Scala] - Help with action composition and accessing Session

222 views
Skip to first unread message

William Bowen

unread,
Sep 19, 2015, 9:12:08 PM9/19/15
to play-framework
I'm relatively new to Play and trying to fulfill a pretty simple use case. The application is protected by a Single Sign On gateway that passes a header to the application with user ID I can then look up against a database to get the user information.

When I detect the header, I want to first look in the session to see if we've already done the DB lookup. If it's already in the session, I can proceed. Otherwise, I can perform the lookup one time and then store the value in the session. I understand Play session is really just a 4k cookie, but that's fine for my purposes.

The problem I've been having is successfully adding the value to the session and having it available in my template to display the user's information on every request. I can't seem to add anything in to the session. I tried a global doFilter and I've been struggling with action composition. Here's a truncated example I'm working with now:

 class UserRequest[A](val userObject : Option[String], request: Request[A]) extends WrappedRequest[A](request)

object SessionAction extends ActionBuilder[Request] {
def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
if (request.session.get("user").isEmpty) {
// The Scala JSON stuff built in doesn't let me just serialize a Java object without decorating it
// And we can't store anything but Strings in Session so....
val mapper = new ObjectMapper();
val user = my.package.Global.apiClient.getUserService().getUserByEmail(request.headers.get("AUTH_USER").get)
try {
val userSerialized = mapper.writeValueAsString(user)
Logger.info(s"Writing serialized string to session for user $userSerialized")
        // Attempt to add it to the session. This doesn't throw an error, but "user" is always None later
request.session + ("user" -> userSerialized)
Logger info ("Is session empty? " + request.session.get("user"))
block(new UserRequest(Some(userSerialized), request))
} catch {
case e: Exception => Logger.warn("Error when trying to load user session", e)
}
}
block(request)
}
}

Even at the end of the Session Action call when I print out if the session is empty, I get "None." I can verify the the DB retrieval and everything is working, it's just storing and retrieving the actual value I'm having trouble with. In my controller then I try to do something like this:

def index = SessionAction {implicit request =>
val userString = request.userObject
  // The docs on Action Composition do something like this but request.userObject doesn't exist for me
Logger.info(s"User request is $userString")
Ok(views.html.index("Page title..."))
}

The end result is I want to be able to display the user name on every template (implicit request) without having to explicitly pass it around.

Thanks in advance for any help.

- William

William Bowen

unread,
Sep 23, 2015, 2:13:12 PM9/23/15
to play-framework
OK, I guess I shouldn't have put code examples. Let me make this simpler.

How do I set a variable one time in the session (detected on request start) and persist it all the way to the template in Play 2.4.3 Scala?

Christian Kaps

unread,
Sep 24, 2015, 2:27:10 AM9/24/15
to play-framework
Hi,

In your code example you declare the wrong action type for the ActionBuilder. You must declare it as ActionBuilder[UserRequest].


Best regards,
Christian

deca...@gmail.com

unread,
Aug 1, 2017, 9:00:12 PM8/1/17
to Play Framework
Did you ever figure out how to do this?

Adam Lane

unread,
Aug 2, 2017, 12:14:20 PM8/2/17
to Play Framework
I am just guessing and could totally be wrong but I think if you want the session to be returned with something added to it, you would have to do something like this...

block(new UserRequest(Some(userSerialized), request.withSession(request.session + ("user" -> userSerialized)) ))
Reply all
Reply to author
Forward
0 new messages