【发布时间】:2020-06-11 15:24:47
【问题描述】:
我需要创建一个基准报告,说明是否在总体方案中:在每个请求上缩小 + GZIP 动态 HTML 响应(通过 GSP 生成),由于解析生成的动态 HTML 字符串,这将导致额外的开销然后使用 Java 库进行压缩(这会导致更小的响应大小)实际上比 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拦截器就不可能修改...?那么是否有任何其他方法可以使用 Grails 3 拦截器来做到这一点,或者我应该手动更新我们拥有的每个控制器操作并在那里执行修改?
【问题讨论】:
-
我认为最好在您的 servlet 容器或 Web 服务器中执行此操作,而不是在应用程序层执行此操作。如果你使用 tomcat 它有这个设置。
-
埃里克说的是对的。与此分开......“但似乎响应体一旦进入afterView拦截器就不可能修改......?”,没错。
afterView在响应写入后调用,所以为时已晚。