Recently, I have shared less code, and I just want to share some relevant experience in optimizing the most code about the compression of the returned html code.
[Reference: http://www.zuidaima.com/share/2633847241772032.htm]
The previous research was implemented through freemarker's native macro:
1
<@compress single_line=true>
2
<html>
3
freemarker template technology
4
</ html>
5
</@compress>
But because there are dozens of template files in the most code, it is too time-consuming and laborious to add them one by one. In addition, if it is not freemarker technology, this mechanism cannot be used. I feel that java should have this technology. To achieve the function of compression, I thought of Filter
HtmlFilter.java
001
package com.zuidaima.filter;
002
003
import java.io.ByteArrayOutputStream;
004
import java.io.IOException;
005
import java.io.PrintWriter;
006
import java.util.ArrayList;
007
import java.util.List;
008
import java.util.regex.Matcher;
009
import java.util.regex.Pattern;
010
011
import javax.servlet.Filter;
012
import javax.servlet.FilterChain;
013
import javax.servlet.FilterConfig;
014
import javax.servlet.ServletException;
015
import javax.servlet.ServletOutputStream;
016
import javax.servlet.ServletRequest;
017
import javax.servlet.ServletResponse;
018
import javax.servlet.http.HttpServletRequest;
019
import javax.servlet.http.HttpServletResponse;
020
import javax.servlet.http.HttpServletResponseWrapper;
021
022
/**
023
*@author www.zuidaima.com
024
**/
025
public class HtmlFilter implements Filter {
026
027
public static final String codePatternStr = "(<|<)p-re[\\w\\W]*?[\\w\\W]*?/p-re[\\w\\W]*?(>|>)";
028
public static final Pattern codePattern = Pattern.compile(codePatternStr,
029
Pattern.CASE_INSENSITIVE);
030
031
private FilterConfig filterConfig = null;
032
033
class CodeFragment {
034
035
private String left;
036
private String fragment;
037
private String right;
038
039
public CodeFragment(String left, String fragment, String right) {
040
this.left = left;
041
this.fragment = fragment;
042
this.right = right;
043
}
044
045
public String getLeft() {
046
return left;
047
}
048
049
public void setLeft(String left) {
050
this.left = left;
051
}
052
053
public String getFragment() {
054
return fragment;
055
}
056
057
public void setFragment(String fragment) {
058
this.fragment = fragment;
059
}
060
061
public String getRight() {
062
return right;
063
}
064
065
public void setRight(String right) {
066
this.right = right;
067
}
068
}
069
070
private static class ByteArrayServletStream extends ServletOutputStream {
071
ByteArrayOutputStream baos;
072
073
ByteArrayServletStream(ByteArrayOutputStream baos) {
074
this.baos = baos;
075
}
076
077
public void write(int param) throws IOException {
078
baos.write(param);
079
}
080
}
081
082
private static class ByteArrayPrintWriter {
083
084
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
085
086
private PrintWriter pw = new PrintWriter(baos);
087
088
private ServletOutputStream sos = new ByteArrayServletStream(baos);
089
090
public PrintWriter getWriter() {
091
return pw;
092
}
093
094
public ServletOutputStream getStream() {
095
return sos;
096
}
097
098
byte[] toByteArray() {
099
return baos.toByteArray();
100
}
101
}
102
103
public class CharResponseWrapper extends HttpServletResponseWrapper {
104
private ByteArrayPrintWriter output;
105
private boolean usingWriter;
106
107
public CharResponseWrapper(HttpServletResponse response) {
108
super(response);
109
usingWriter = false;
110
output = new ByteArrayPrintWriter();
111
}
112
113
public byte[] getByteArray() {
114
return output.toByteArray();
115
}
116
117
@Override
118
public ServletOutputStream getOutputStream() throws IOException {
119
// will error out, if in use
120
if (usingWriter) {
121
super.getOutputStream();
122
}
123
usingWriter = true;
124
return output.getStream();
125
}
126
127
@Override
128
public PrintWriter getWriter() throws IOException {
129
// will error out, if in use
130
if (usingWriter) {
131
super.getWriter();
132
}
133
usingWriter = true;
134
return output.getWriter();
135
}
136
137
public String toString() {
138
return output.toString();
139
}
140
}
141
142
public void doFilter(ServletRequest request, ServletResponse response,
143
FilterChain chain) throws IOException, ServletException {
144
HttpServletRequest _request = (HttpServletRequest) request;
145
if (_request.getRequestURI().indexOf("update") != -1
146
|| _request.getRequestURI().indexOf("create") != -1) {
147
chain.doFilter(request, response);
148
return;
149
}
150
CharResponseWrapper wrappedResponse = new CharResponseWrapper(
151
(HttpServletResponse) response);
152
chain.doFilter(request, wrappedResponse);
153
byte[] bytes = wrappedResponse.getByteArray();
154
155
String contentType = wrappedResponse.getContentType();
156
if (contentType != null && contentType.matches(".*?(html|json).*?")) {
157
String out = new String(bytes);
158
Matcher matcher = codePattern.matcher(out);
159
List<CodeFragment> codeFragments = new ArrayList<CodeFragment>();
160
while (matcher.find()) {
161
String fragment = matcher.group(0);
162
String left = matcher.group(1);
163
String right = matcher.group(2);
164
CodeFragment codeFragment = new CodeFragment(left, fragment,
165
right);
166
codeFragments.add(codeFragment);
167
// 占位符<pr-e>idx</pr-e>
168
out = out.replace(fragment, left + "p-re" + right
169
+ codeFragments.size() + left + "/p-re" + right);
170
}
171
out = out.replaceAll("[\r\n]", "").replaceAll(">\\s*?<", "><")
172
.trim();
173
// 还原占位符
174
for (int i = 0; i < codeFragments.size(); i++) {
175
CodeFragment codeFragment = codeFragments.get(i);
176
String fragment = codeFragment.getFragment();
177
String left = codeFragment.getLeft();
178
String right = codeFragment.getRight();
179
out = out.replace(left + "p-re" + right + (i + 1) + left
180
+ "/p-re" + right, fragment);
181
}
182
response.getOutputStream().write(out.getBytes());
183
} else {
184
response.getOutputStream().write(bytes);
185
}
186
}
187
188
@Override
189
public void init(FilterConfig filterConfig) throws ServletException {
190
this.filterConfig = filterConfig;
191
}
192
193
@Override
194
public void destroy() {
195
filterConfig = null;
196
}
197
}
The fresh code sharing that has just been launched, I believe it will be helpful to Niu Niu.
Note:
1. The operations of creating and editing classes are not compressed because the traffic volume is not large
. 2. The code inside <pre></pre> is not processed
. 3. Only the content type is html and json. Before
compression Compare with the size of the compressed html code as shown in the figure below:
Java servlet implements the filter code returned after
compressing the html web page. The source code
java servlet before compression implements the filter code returned after compressing
the html web page. The compressed source code
java servlet compresses the html web page and returns it. The filter code implementation of the
other may not have a great impact on seo, after all, the html structure has not been changed.
Java servlet implements the filter code returned after compressing the html web page
Guess you like
Origin http://10.200.1.11:23101/article/api/json?id=326802495&siteId=291194637
Recommended
Ranking