在 Grails 中是否有更简单的方法来进行内容协商响应?

发布于 2024-12-21 08:01:27 字数 550 浏览 1 评论 0原文

根据 Grails 用户指南中的内容,推荐方法根据内容协商发送不同的内容格式是使用 withFormat 块:

import grails.converters.XML
class BookController {

    def list() {
        def books = Book.list()
        withFormat {
            html bookList: books
            js { render "alert('hello')" }
            xml { render books as XML }
        }
    }
}

但是,我希望所有控制器方法的响应都能执行此操作。有没有比在每个内容返回操作末尾简单地复制粘贴 withFormat 块更好的方法来实现此行为?

From what is in the Grails user guide, the recommended way to send different content formats based on the content negotiation is to use a withFormat block:

import grails.converters.XML
class BookController {

    def list() {
        def books = Book.list()
        withFormat {
            html bookList: books
            js { render "alert('hello')" }
            xml { render books as XML }
        }
    }
}

However, I would like the responses of ALL my controller methods to do this. Is there a better way to get this behavior than to simply copy-paste the withFormat block at the end of every content-returning action?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘虞初梦 2024-12-28 08:01:27

我脑海中首先出现的两件事是拦截器和过滤器:

http:// grails.org/doc/1.3.7/ref/Controllers/afterInterceptor.html

http://grails.org/doc/latest/guide/ 6.%20The%20Web%20Layer.html#6.6 过滤器

拦截器将不起作用,因为您无法执行 withFormat。真糟糕,因为那更加全球化。

过滤器将在每个控制器的基础上工作,但至少您可以最大限度地减少该级别的重复。

def afterInterceptor = {model, modelAndView ->
    withFormat {
        html { model }
        js { render "alert('hello')" }
        xml { render model as XML }
    }
}

这在我的测试项目中对我有用。我尝试将这个闭包放入它自己的类中并混合在类中,以便您可以做一个更全局的解决方案......不过没有骰子。

也许你所有的 afterInterseptors 将模型 modelAndView 传递给一个公共类?这似乎有效:)(在回答时努力寻找答案)

@Mixin(AfterInterceptorWithFormat)
class FirstController {

    def action1 = {}
    def action2 = {}

    def afterInterceptor = {model, modelAndView ->
        performAfterInterceptor(model, modelAndView)
    }
}

class AfterInterceptorWithFormat {

    def performAfterInterceptor(model, modelAndView) {
        withFormat {
            html { model }
            js { render "alert('hello')" }
            xml { render model as XML }
        }
    }
}

尝试一下,让我知道你的想法。

First two things that popped in my head were Interceptors and Filters:

http://grails.org/doc/1.3.7/ref/Controllers/afterInterceptor.html

http://grails.org/doc/latest/guide/6.%20The%20Web%20Layer.html#6.6 Filters

Interceptors won't work because you can't do the withFormat. Bummer because that's a more global.

Filters will work on a controller per controller basis, but at least you'd be minimizing your duplication at that level.

def afterInterceptor = {model, modelAndView ->
    withFormat {
        html { model }
        js { render "alert('hello')" }
        xml { render model as XML }
    }
}

This worked for me in my test project. I tried putting that closure into it's own class and mixing in the class so that you could do a more global solution... no dice though.

Maybe have all of your afterInterseptors pass the model, modelAndView to a common class? That seems to work :) (working towards an answer while answering)

@Mixin(AfterInterceptorWithFormat)
class FirstController {

    def action1 = {}
    def action2 = {}

    def afterInterceptor = {model, modelAndView ->
        performAfterInterceptor(model, modelAndView)
    }
}

class AfterInterceptorWithFormat {

    def performAfterInterceptor(model, modelAndView) {
        withFormat {
            html { model }
            js { render "alert('hello')" }
            xml { render model as XML }
        }
    }
}

Give that a whirl and let me know what you think.

裸钻 2024-12-28 08:01:27

我最终所做的就是简单地调整默认的 CRUD 模板,以在每个方法的末尾添加 withFormat 块。

我意识到我真正想要的只是内容协商的 CRUD,因此将代码放入模板中就是我所需要的。

我的应用程序的非 CRUD 部分的其余控制器不需要 no-html 输出,因此除了 CRUD 控制器之外,我不需要对任何内容进行内容协商。

What I ended up doing is to simply adjust the default CRUD templates to have the withFormat block at the end of each method.

I realized that what I really wanted was just content-negotiated CRUD, so putting the code into the templates was all I needed for that.

The rest of the controllers for the non-crud parts of my application did not need no-html output, so I didn't need content negotiation on anything but the crud controllers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文