I am just starting to use Services in Grails and I am having an issue when trying to render a page from inside a service, I have tried a few methods as shown below with no luck:
Service Call 1:
GroupCheckService.isEnabled(userObjects.group.notenabled)
Service Attempt 1:
import grails.gsp.PageRenderer
class GroupCheckService {
PageRenderer groovyPgeRenderer
static transactional = false
def isEnabled(boolean notenabled) {
if(notenabled == true){
groovyPgeRenderer.render(view: '/locked')
}else{
return
}
}
}
Service Call 2:
GroupCheckService.isEnabled(render, userObjects.group.notenabled)
Service Attempt 2:
class GroupCheckService {
PageRenderer groovyPgeRenderer
static transactional = false
def isEnabled(Closure render, boolean notenabled) {
if(notenabled == true){
render.call view:"/locked"
}else{
return
}
}
}
Now when I try method 1 I don't get an error but the page is not rendered when the IF is satisfied, with method 2 I get the following error:
no such property render
I would really appreciate some advise or help on how to achieve this, thanks in advance :)
You shouldn't render views from service - this is a part for the controller.
Use the service for business logic and/or (transactional) database operations.
From grails docs:
Services in Grails are the place to put the majority of the logic in your application, leaving controllers responsible for handling request flow with redirects and so on.
If you realy want to render a view from service, mrhaki has blogged about using the PageRenderer
from service.
import grails.gsp.PageRenderer
class GroupCheckService {
PageRenderer groovyPageRenderer
def isEnabled(Closure render, boolean notenabled) {
if(notenabled == true){
groovyPageRenderer.render view: "/locked"
}else{
return
}
}
}
Notice that you can't use Sitemesh
layouts due to the PageRenderer
works outside of the request scope.
The best way is to redesign your application to leave the render stuff in the controller.
First of all - it's very bad practice to render HTTP response from a service.
As about your code - you have to use first approach, with groovyPgeRenderer.render
. But you aren't using result of this call. It's a method that returns a String
(see docs)
So, you need to put that string into HTTP response manually. You can get HttpServlet response from Controller, or from RequestContextHolder.currentRequestAttributes()
(see docs). Like:
String html = groovyPageRenderer.render(view: '/locked')
def response = RequestContextHolder.currentRequestAttributes().response
response.setStatus(200)
response.setContentType('text/html')
response.writer.write(html)