如何缩小 Spring 中的动态 HTML 响应?
How do I minify dynamic HTML responses in Spring?
遵循 Google 的 pagespeed 建议,我希望缩小 Spring 应用程序的 HTML 响应。我不是指 GZip,我的意思是在 HTML 发送之前从 HTML 中删除注释和空格。
我想动态地而不是在我的模板中执行此操作。我的模板包含许多有用的评论,但不应作为回复的一部分。
以下是我的控制器;
@Controller
public class IndexController {
@GetMapping("/")
public ModelAndView index() {
Data data = ....
return new ModelAndView("index", data);
}
}
我设法通过将 javax.servlet.Filter
component that is using com.googlecode.htmlcompressor
添加到 Spring
来做到这一点
首先是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>
遵循 Google 的 pagespeed 建议,我希望缩小 Spring 应用程序的 HTML 响应。我不是指 GZip,我的意思是在 HTML 发送之前从 HTML 中删除注释和空格。
我想动态地而不是在我的模板中执行此操作。我的模板包含许多有用的评论,但不应作为回复的一部分。
以下是我的控制器;
@Controller
public class IndexController {
@GetMapping("/")
public ModelAndView index() {
Data data = ....
return new ModelAndView("index", data);
}
}
我设法通过将 javax.servlet.Filter
component that is using com.googlecode.htmlcompressor
添加到 Spring
首先是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>