The server uses Gzip to compress the JSON datagram "socket write error: Connection reset by peer." error

        Existing server deployment and problems:


Cause Analysis:

        After JsonDispatherHandler performs write and flush methods on response.getWriter(), response.getWriter() is closed by the web server, so when the output stream is obtained and written in the filter, the error of Connection reset by peer will be thrown.

 

Solution:

        Create a new JsonDispatcherHandlerWithGzip.java, inherit the JsonDispatherHandler to rewrite the corresponding method, and modify the configuration file to change the configuration file related configuration to JsonDispatcherHandlerWithGzip.java.

public class JsonDispatcherHandlerWithGzip extends JsonDispatcherHandler {
	
    public final static String RESULT = "JsonView4WebDispatcherHandler_result";
    private static final String NULL_JSON_STRING = "{}";
    private String defaultContentType = "text/html";

    @Override
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        long startTime = System.currentTimeMillis();
        addResponseHeader(response);
        byte[] bytes = (byte[]) model.get(RESULT);
        if (isGZipEncoding(request)) {
            byte[] outData = null;
            if (bytes.length > 512) {
                byte [] gzipData = toGzipBytes (bytes);
                response.setHeader("Content-Encoding", "gzip");
                response.setHeader("Transfer-Encoding", "");
                response.setContentLength(gzipData.length);
                outData = gzipData;
                PASLogUtils.debugTrace("gzip end ,cost:" + (System.currentTimeMillis() - startTime));
            } else {
                outData = bytes.length == 0 ? NULL_JSON_STRING.getBytes(response.getCharacterEncoding()):bytes;
            }
            ServletOutputStream output = response.getOutputStream();
            output.write(outData);
            output.flush();
        }else{
            String resp = bytes.length == 0 ? NULL_JSON_STRING : new String(bytes, response.getCharacterEncoding());
            PASLogUtils.debugTrace("Rest result =" + resp);
            Writer out = response.getWriter();        
            out.write(resp);
            out.flush();
        }
    }

    /*
     * Add response header information
     */
    private void addResponseHeader(HttpServletResponse response) {
        if (!StringUtils.hasText(response.getContentType())) {
            StringBuffer contentTypeBuffer = new StringBuffer();
            contentTypeBuffer.append(defaultContentType);
            contentTypeBuffer.append(";charset=" + response.getCharacterEncoding());
            response.setContentType(contentTypeBuffer.toString());
        }
    }
    /*
     * Determine whether the browser supports GZIP
     */
    private boolean isGZipEncoding(HttpServletRequest request) {
        boolean flag = false;
        String encoding = request.getHeader("Accept-Encoding");
        if (encoding.indexOf("gzip") != -1) {
            flag = true;
        }
        return flag;
    }
    
    public static byte[] toGzipBytes(byte[] srcData) {
        if (srcData == null || srcData.length == 0) {
            return null;
        }
        
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        
        GZIPOutputStream gzip = null;
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(srcData);
        } catch (IOException e) {
            PASLogUtils.debugErorr (e.getMessage ());
        } finally {
            if (gzip != null) {
                try {
                    gzip.close();
                } catch (IOException e) {
                    e.printStackTrace ();
                }
            }
        }
        return out.toByteArray();
    }
}

        So the problem is solved. Pay special attention to the statement response.setHeader("Transfer-Encoding", ""); Transfer-Encoding: chunked means that the length of the output content cannot be determined, and ordinary static pages, pictures, etc. basically do not use this. For details, please refer to http://bijian1013.iteye.com/blog/2280945 .

        Here I purposely did the following test:

        1. Remove the statement response.setHeader("Transfer-Encoding", "");, no error is reported in the request background, but the browser fails to display normally. The analysis found that the length and Content- Inconsistent Length lengths cause browsers to fail to parse them correctly.


        2.将response.setHeader("Transfer-Encoding", "");改成将response.setHeader("Transfer-Encoding", "chunked");报“Could not complete request java.net.SocketException: Connection reset by peer: socket write error”错。

        3. If the two statements, response.setHeader("Transfer-Encoding", ""); and r esponse.setContentLength(gzipData.length); are removed, it will be normal. At this point, use http Watch to see the following information:



Guess you like

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