我需要创建一个基准报告,从大的方面来说:对每个请求进行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拦截器来完成这个任务,或者我应该手动更新我们的每个控制器操作,并在那里执行修改?
这就是我喜欢使用拦截器的原因。
拦截器的after()部分可以在模型从控制器返回后对其进行操作(其中'before()'在请求被发送到控制器之前对其进行操作)。
这允许您在返回客户端之前对一组端点(或一个特定端点)的所有数据进行操作。
如果你想渲染到一个视图上你在拦截器中而不是在控制器中进行,你只是从控制器中返回数据。