Java servlet implements the filter code returned after compressing the html web page

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.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326802495&siteId=291194637