开发者

How to prevent Grails from rendering the default view?

I'm using Grails 1.2.1. I have this method in my controller …

class SocialMediaCacheProxyController {

    def index = {       
        def url = params.url
        if (params.dumpAll != null) {
            transportCacheService.processCacheDump(request.getRemoteAddr(), response)
        } else if (url != null) {
            doCacheTransport(request, response)
        }   // if
    }

Problem is, both execution paths write content to the response. However, I think Grails is trying to render a page at the end of the index method, because I repeatedly get the below error after invoking this method …

1339754 [http-8080-4] ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/socialmediaproxy].[default]  - Servlet.service() for servlet default threw exception
java.lang.IllegalStateException: response.getWriter() called after response.getOutputStream()
    at org.codehaus.groovy.grails.web.sitemesh.GrailsPageResponseWrapper$GrailsBuffer.getWriter(GrailsPageResponseWrapper.java:284)
    at org.codehaus.groovy.grails.web.sitemesh.Grails开发者_StackOverflowPageResponseWrapper$3.activateDestination(GrailsPageResponseWrapper.java:125)

Any ideas how I can get Grails to stop rendering anything after my method is complete? Thanks, - Dave


If you don't tell Grails what to render, it will render based on convention. In your case, it is looking for an index.gsp. Controllers must return something. That's the whole point. So you can either use the convention and create an index.gsp that gets returned, or you can manually implement the render() method.

http://grails.org/doc/latest/ref/Controllers/render.html


It looks like most of the controller code that works with the ModelAndView keeps an eye on whether or not the ServletResponse has been committed.

I would posit that you could call response.flushBuffer() at the end of your controller action. This will cause the response to be marked as committed, and the controller will not return a ModelAndView.

An alternative would be to call response.outputStream.flush(), which would also result in the response being committed. This is what I usually end up doing after manually working with the response (e.g. for file downloads).

Note: I'm not sure where this falls within the realm of "best practices" - usually you're supposed to rely on the container to handle the flushing of the servlet streams. It's possible that there will be inadvertent side-effects by doing this. You'll probably have to test it out and see what happens with your app and the container you run it in.


I think you're trying to do something counter to the design of an MVC application. Controllers exist to send you somewhere based on parameters. Maybe you could look at using a Service instead, through an AJAX call. Or, if your controller action is changing data that you want to show, you could just redirect back to the page that the call came from. Start here:

http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html

http://grails.org/doc/1.0.x/guide/8.%20The%20Service%20Layer.html


I think Grails maybe forwarding to index.gsp, because it does so by default when you don't return a value.

Therefore, i think you should return null at the end of the index-closure to signal grails that you have already written everything you wanted to the output stream.


try this render (view: "/the name of the page", model: [text:'hi there')

NB if u want to render a template instead of "view" you put "template"

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜