【问题标题】:How do I minify dynamic HTML responses in Spring?如何在 Spring 中缩小动态 HTML 响应?
【发布时间】:2018-03-07 12:09:24
【问题描述】:

按照 Google 的 pagespeed 建议,我希望缩小我的 Spring 应用程序的 HTML 响应。我不是指 GZip,我是指在将 HTML 发送到网络之前从 HTML 中删除 cmets 和空格。

我想动态而不是在我的模板中执行此操作。我的模板包含许多有用的 cmets,但不应成为响应的一部分。

下面是我的控制器;

@Controller
public class IndexController {

    @GetMapping("/")
    public ModelAndView index() {
        Data data = ....
        return new ModelAndView("index", data);
    }
}

【问题讨论】:

标签: java html spring spring-boot minify


【解决方案1】:

我设法通过在 Spring 中添加一个使用 com.googlecode.htmlcompressorjavax.servlet.Filter 组件来做到这一点

首先是Filter

@Component
public class HtmlFilter implements Filter {
    protected FilterConfig config;

    public void init(FilterConfig config) throws ServletException {
        this.config = config;
    }

    public void destroy() {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        ServletResponse newResponse = response;

        if (request instanceof HttpServletRequest) {
            newResponse = new CharResponseWrapper((HttpServletResponse) response);
        }

        chain.doFilter(request, newResponse);

        if (newResponse instanceof CharResponseWrapper) {
            String text = newResponse.toString();
            if (text != null) {
                HtmlCompressor htmlCompressor = new HtmlCompressor();
                response.getWriter().write(htmlCompressor.compress(text));
            }
        }
    }
}

和相关的CharResponseWrapper;

class CharResponseWrapper extends HttpServletResponseWrapper {
    protected CharArrayWriter charWriter;
    protected PrintWriter writer;
    protected boolean getOutputStreamCalled;
    protected boolean getWriterCalled;

    public CharResponseWrapper(HttpServletResponse response) {
        super(response);

        charWriter = new CharArrayWriter();
    }

    public ServletOutputStream getOutputStream() throws IOException {
        if (getWriterCalled) {
            throw new IllegalStateException("getWriter already called");
        }

        getOutputStreamCalled = true;
        return super.getOutputStream();
    }

    public PrintWriter getWriter() throws IOException {
        if (writer != null) {
            return writer;
        }
        if (getOutputStreamCalled) {
            throw new IllegalStateException("getOutputStream already called");
        }
        getWriterCalled = true;
        writer = new PrintWriter(charWriter);
        return writer;
    }

    public String toString() {
        String s = null;

        if (writer != null) {
            s = charWriter.toString();
        }
        return s;
    }
}

效果非常好。把一个难看的 html 转换成这样;

<!DOCTYPE HTML>
<html>
<head>
    <title>
        A Simple
        <!--        Test-->
        HTML Document
        <!--        Test-->

    </title>



</head>
<body>
                 <p>This is a very simple HTML document</p>


                 <!--        Test-->



<p>It only has two<!--        Test--> paragraphs</p>

                 <!--        Test-->

</body>
</html>

进入这个;

<!DOCTYPE HTML> <html> <head> <title> A Simple HTML Document </title> </head> <body> <p>This is a very simple HTML document</p> <p>It only has two paragraphs</p> </body> </html>

【讨论】:

  • 如果不使用统计,htmlCompressor可能会缓存在类成员中
  • 我错了还是CharResponseWrapper类中的方法getOutputStream()不是必需的并且可以安全删除?似乎无论如何都可以工作......
猜你喜欢
  • 1970-01-01
  • 2012-07-27
  • 2018-07-07
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多