Reputation: 3664
I'm using Grails 1.3.4 and Spring Security Core 1.0.1.
If I choose the option "remember me" when I login sometimes when I load the page again it gives this error:
errors.GrailsExceptionResolver Error executing tag <g:render>: Error executing tag <sec:ifLoggedIn>: Cannot create a session after the response has been committed at D:/Workspace/steer/grails-app/views/templates/_header.gsp:18 at D:/Workspace/steer/grails-app/views/layouts/main.gsp:29
org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException: Error executing tag <g:render>: Error executing tag <sec:ifLoggedIn>: Cannot create a session after the response has been committed at D:/Workspace/steer/grails-app/views/templates/_header.gsp:18 at D:/Workspace/steer/grails-app/views/layouts/main.gsp:29
at D__Workspace_steer_grails_app_views_layouts_main_gsp$_run_closure2.doCall(D__Workspace_steer_grails_app_views_layouts_main_gsp:66)
at D__Workspace_steer_grails_app_views_layouts_main_gsp$_run_closure2.doCall(D__Workspace_steer_grails_app_views_layouts_main_gsp)
at D__Workspace_steer_grails_app_views_layouts_main_gsp.run(D__Workspace_steer_grails_app_views_layouts_main_gsp:75)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException: Error executing tag <sec:ifLoggedIn>: Cannot create a session after the response has been committed at D:/Workspace/steer/grails-app/views/templates/_header.gsp:18
at D__Workspace_steer_grails_app_views_templates__header_gsp.run(D__Workspace_steer_grails_app_views_templates__header_gsp:35)
... 4 more
Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed
at D__Workspace_steer_grails_app_views_templates__header_gsp$_run_closure1.doCall(D__Workspace_steer_grails_app_views_templates__header_gsp:22)
at D__Workspace_steer_grails_app_views_templates__header_gsp$_run_closure1.doCall(D__Workspace_steer_grails_app_views_templates__header_gsp)
at grails.plugins.springsecurity.SecurityTagLib$_closure6.doCall(SecurityTagLib.groovy:130)
... 5 more
Does anyone know why I get this error?
_Hearer.gsp
<%@ page import="com.mycompany.myapp.partymodel.roles.SystemUserRole" %>
<sec:ifLoggedIn>
<%
def userId = session.SPRING_SECURITY_CONTEXT?.authentication?.principal?.id
def userDetails = SystemUserRole.get(userId)
%>
<div class="mast_head">
<ul>
<li>Welcome ${userDetails?.party?.firstName}</li>
<li> | </li>
<li><a href="${createLink(controller: "systemUserRole", action: "editprofile")}">Profile</a></li>
<li> | </li>
<li><a href="${createLink(controller: "systemUserRole", action: "changepassword")}">Edit Password</a></li>
<li> | </li>
<li><a href="${createLink(controller: "logout", action: "index")}">Sign Out</a></li>
</ul>
</div>
</sec:ifLoggedIn>
<div id="grailsLogo" class="logo">
<a href="http://www.mycompany.in/"><img src="${resource(dir:'images',file:'mycompany_trans.png')}" alt="Grails" border="0" height=67 /></a>
</div>
LayoutTagLib.groovy
package com.mycompany.myapp.layout
import com.mycompany.myapp.trips.Trip
class LayoutTagLib {
static namespace = "my"
def header = { attrs ->
Trip.withNewSession {
sec.ifLoggedIn() {
out << "<div class="mast_head">
<ul>
<li>Welcome ${userDetails?.party?.firstName}</li>
<li> | </li>
<li><a href="${createLink(controller: "systemUserRole", action: "editprofile")}">Profile</a></li>
<li> | </li>
<li><a href="${createLink(controller: "systemUserRole", action: "changepassword")}">Edit Password</a></li>
<li> | </li>
<li><a href="${createLink(controller: "logout", action: "index")}">Sign Out</a></li>
</ul>
</div>"
}
}
}
}
Upvotes: 2
Views: 445
Reputation:
I think this is a restriction about using that kind of tags in layouts
since it's processed by SiteMesh after the hibernate session is commited.
The solution is to wrap this in a session (withNewSession
closure of a domain class). Something like:
LayoutTagLib is a TagLib, you can create with command create-taglib
grails create-tag-lib com.app.layout.LayoutTagLib
Important: Replace the "SomeDomain" with any existing domain class of your application.
class LayoutTagLib {
static namespace = "my"
def header = { attrs ->
SomeDomain.withNewSession {
sec.ifLoggedIn() {
out << "Logged In"
}
}
}
}
The out
is the html that will be printed in the page. So change it with whatever you have in your header template.
Then you have a _header.gsp correct? Just replace the <sec:ifLoggedIn>
block with the call of your taglib.
<my:header />
EDIT:
You need to wrap your query's inside the withNewSession
. And also remove the content from your header, just calling the taglib instead. To get the user data you can use the springSecurityService
.
package com.mycompany.myapp.layout
import com.mycompany.myapp.trips.Trip
class LayoutTagLib {
//dependency injection of the plugin service
def springSecurityService
static namespace = "my"
def header = { attrs ->
Trip.withNewSession {
sec.ifLoggedIn() {
def userId = springSecurityService.currentUser.id
def userDetails = SystemUserRole.get(userId)
//better transform this in a private method or a template!
out << """<div class="mast_head">
<ul>
<li>Welcome ${userDetails?.party?.firstName}</li>
<li> | </li>
<li><a href="${createLink(controller: "systemUserRole", action: "editprofile")}">Profile</a></li>
<li> | </li>
<li><a href="${createLink(controller: "systemUserRole", action: "changepassword")}">Edit Password</a></li>
<li> | </li>
<li><a href="${createLink(controller: "logout", action: "index")}">Sign Out</a></li>
</ul>
</div>"""
}
}
}
}
_header.gsp
<my:header/> <!-- This line will call your taglib!! -->
<div id="grailsLogo" class="logo">
<a href="http://www.mycompany.in/"><img src="${resource(dir:'images',file:'mycompany_trans.png')}" alt="Grails" border="0" height=67 /></a>
</div>
Upvotes: 1