在发送至客户端之前,修改Grails 3中响应的渲染字符串。

问题描述 投票:0回答:1

我需要创建一个基准报告,从大的方面来说:对每个请求进行minifying + GZIP动态HTML响应(通过GSP生成),这将导致额外的开销,因为对生成的动态HTML字符串进行解析,然后使用Java库进行压缩(这导致响应大小较小),实际上比不进行minifying的GZIP更好(这导致响应时间更快,但响应大小稍大)。我感觉这种 "改进" 也许 是微不足道的,但我需要基准报告来支持它的团队。

为了做到这一点,我修改了控制器的动作,像这样。

// import ...MinifyPlugin
class HomeController {
    def get() {
        Map model = [:]
        String htmlBody = groovyPageRenderer.render(view: "/get", model: model)
        // This adds a few milliseconds and reduce few characters.
        htmlBody = MinifyPlugin.minifyHtmlString(htmlBody)
        render htmlBody
    }
}

但Grails项目有近百个操作,对每个现有的操作都这样做是不切实际的,也是不可维护的,尤其是在基准测试之后,我们可能决定不对HTML响应进行最小化。所以我想在一个 Interceptor 而不是。

void afterView() {
    if(response.getContentType().contains("text/html")) {
        // This throws IllegalStateException: getWriter() has already been called for this response
        OutputStream servletOutputStream = response.getOutputStream()

        String htmlBody = new String(servletOutputStream.toByteArray())
        htmlBody = MinifyingPlugin.minifyHtmlString(htmlBody)
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()
        byteArrayOutputStream.write(htmlBody.getBytes())

        response.setCharacterEncoding("UTF-8")
        response.setContentType("text/html")
        response.outputStream << byteArrayOutputStream
    }
}

但似乎一旦进入反应体,就不可能对其进行修改。afterView interceptor...?那么,是否有其他方法可以使用Grails 3拦截器来完成这个任务,或者我应该手动更新我们的每个控制器操作,并在那里执行修改?

html servlets grails
1个回答
0
投票

这就是我喜欢使用拦截器的原因。

拦截器的after()部分可以在模型从控制器返回后对其进行操作(其中'before()'在请求被发送到控制器之前对其进行操作)。

这允许您在返回客户端之前对一组端点(或一个特定端点)的所有数据进行操作。

如果你想渲染到一个视图上你在拦截器中而不是在控制器中进行,你只是从控制器中返回数据。

© www.soinside.com 2019 - 2024. All rights reserved.