Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using scala and java in play framework 2.1 : Session usage

I'm currently using the session() of play framework in my template :

@if(session().get("email")==null){
    <li><a href="@controllers.routes.General.login">Login</a></li>
}else{
    <li><a href="@controllers.routes.General.logout">Logout</a></li>
}

This template is used in all of my views. Some of these views are controlled by a Java controller, and some are with a Scala controller.

When I click on links that lead to Java controllers, I have no problems, the links for login and logout are correctly handled.

When I click on links that lead to Scala controllers, I get a [RuntimeException: There is no HTTP Context available from here.]

From what I read in here about scala controllers, I understood that they didn't return the http context when rendering a page, but I really want to be able to use the session in my template.

I thought about using an argument session() in my view, templates and controllers, but I believe that there will be a conflict between the java session (play.mvc.http.session) and the scala session (play.api.mvc.session) when play will compile the html pages.

Am I stuck? Is there a possibility to force scala controllers to give back the http context ?

like image 780
Saffron Avatar asked Nov 02 '22 19:11

Saffron


1 Answers

The root cause maybe the Java controllers and Scala controllers are handled differently. I have my project in Java first, and then try to add more Scala controllers. I also came across this problem (BTW, I am using Play 2.3.2).

I tried to fix this by setting my own Http.Context in the TheadLocal variable using my own ActionBuilder.

import play.api.mvc._
import scala.concurrent.Future
import play.mvc.Http.Context
import play.core.j.JavaHelpers

object ContextAction extends ActionBuilder[Request] {

  def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
    Context.current.set(JavaHelpers.createJavaContext(request))
    block(request)
  }
}

Then my Scala controller actions simply use this ContextAction instead:

class TestController extends Controller {
  def test = ContextAction { implicit request =>
    Ok(views.html.index())
  }
}

And this way the index template can access all request() / session() / etc.

like image 133
user2138120 Avatar answered Nov 10 '22 15:11

user2138120