Play Framework Template Engine, static member passed to render cause NullPointerException
I've struggled with a NullPointerException in my template for a while and haven't been able to find any help online so I'm hoping that someone here can shed some light on my issue.
I have created my own "Base Controller" that all my other controllers extend. The base controller contains a static member which holds the users session (not the play session but a db model):
public class Home extends SessionController {
...
}
public class SessionController extends Controller {
protected static SessionDao siteSession;
}
To my problem... I need to pass this static session member to my template. In Home I do the following:
public class Home extends SessionController {
public static void index() {
render(siteSession);
}
}
And then in my template I do:
${siteSession.search.query}
This causes a NullPointerException on siteSession (I am sure it is set properly in the Controller before passing it to render()).
I've been messing around quite a bit and managed to get the following to work:
public class Home extends SessionController {
public static void index() {
// Just setting mySession to siteSession
SessionDao mySession = siteSession;
render(siteSession);
}
}
And then in my template I do:
${mySession.search.query}
Note that I use mySession in the template and I still pass siteSession to render() in my action. For some reason this works, I get my session object and all is well but this can't really be the way to go about doing this. I shouldn't even be able to access mySession in the template since it was never passed to render().
If someone can shed some light on this I would much appreciate it.
My preferred scenario would be to let SessionController override render and pass the siteSessio开发者_运维百科n object to the template engine "automatically". If anyone has any suggestions on how I go about doing that I would appreciate it as I have tried and was unable to gain access to any and all objects in the template (this snippet doesn't work):
public class Home extends SessionController {
public static void render(Object ... args) {
if (args == null) {
args = new Object[1];
}
args[args.length] = siteSession;
Controller.render(args);
}
}
I am not sure why the mySession
object is available in your template when you are not passing it in through the render() method, but to answer your question on how you can get objects automatically passed into your templates, is fairly trivial.
In your base controller, create a method that is annotated with the @Before
annotation, and add the required objects to the renderArgs
object. For Example...
public class SessionController extends Controller {
protected static SessionDao siteSession;
@Before
static void populateRenderArgs() {
renderArgs.put("siteSession", siteSession);
// etc... add any other global template arguments here
}
}
For more info on the renderArgs object, check here and look for the "Add data to the template scope" section.
精彩评论