You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "MK (JIRA)" <ji...@apache.org> on 2011/01/04 18:46:46 UTC

[jira] Commented: (WW-3519) JSONUtil writeJSONToResponse does not respect content ecoding when GZip output is enabled

    [ https://issues.apache.org/jira/browse/WW-3519?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12977373#action_12977373 ] 

MK commented on WW-3519:
------------------------

I think original code block is (version 2.2.1):

        if (serializationParams.isGzip()) {
            response.addHeader("Content-Encoding", "gzip");
            GZIPOutputStream out = null;
            InputStream in = null;
            try {
                out = new GZIPOutputStream(response.getOutputStream());
-->                in = new ByteArrayInputStream(json.getBytes());
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            } finally {
                if (in != null)
                    in.close();
                if (out != null) {
                    out.finish();
                    out.close();
                }
            }

        } else {
            response.setContentLength(json.getBytes(serializationParams.getEncoding()).length);
            PrintWriter out = response.getWriter();
            out.print(json);
        }

and it should be changed to 


        if (serializationParams.isGzip()) {
            response.addHeader("Content-Encoding", "gzip");
            GZIPOutputStream out = null;
            InputStream in = null;
            try {
                out = new GZIPOutputStream(response.getOutputStream());
-->                in = new ByteArrayInputStream(json.getBytes(serializationParams.getEncoding()));
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            } finally {
                if (in != null)
                    in.close();
                if (out != null) {
                    out.finish();
                    out.close();
                }
            }

        } else {
            response.setContentLength(json.getBytes(serializationParams.getEncoding()).length);
            PrintWriter out = response.getWriter();
            out.print(json);
        }

> JSONUtil writeJSONToResponse does not respect content ecoding when GZip output is enabled
> -----------------------------------------------------------------------------------------
>
>                 Key: WW-3519
>                 URL: https://issues.apache.org/jira/browse/WW-3519
>             Project: Struts 2
>          Issue Type: Bug
>    Affects Versions: 2.1.8.1
>            Reporter: David Connard
>   Original Estimate: 2h
>  Remaining Estimate: 2h
>
> When JSONUtil is used to write JSON to a response output stream via GZIP encoding, and that JSON contains extended UTF-8 characters, then the JSON can fail to decode correctly.
> We are seeing this occur when we use the JSONResult class to send an action result to be converted to JSON.  If our result data contains a weird character, eg.  Â in this case, then iPhone clients fail to parse that JSON result.
> The issue is that the response headers say:
>     Content-Type=application/json;charset=UTF-8
> which matches the Struts default.  This works fine when you are not GZip encoded, as the else condition in the following code block (nb. from JSONUtil, starting line 231) is executed:
>         if (serializationParams.isGzip()) {
>             response.addHeader("Content-Encoding", "gzip");
>             GZIPOutputStream out = null;
>             InputStream in = null;
>             try {
>                 out = new GZIPOutputStream(response.getOutputStream());
>                 in = new ByteArrayInputStream(json.getBytes(serializationParams.getEncoding()));
>                 byte[] buf = new byte[1024];
>                 int len;
>                 while ((len = in.read(buf)) > 0) {
>                     out.write(buf, 0, len);
>                 }
>             } finally {
>                 if (in != null)
>                     in.close();
>                 if (out != null) {
>                     out.finish();
>                     out.close();
>                 }
>             }
>         } else {
>             response.setContentLength(json.getBytes(serializationParams.getEncoding()).length);
>             PrintWriter out = response.getWriter();
>             out.print(json);
>         }
> ... and this uses the response writer, which handles the encoding for you.
> However, if you have GZip enabled, then the if condition is executed instead, whereby you encode the string to bytes, and you are not doing so using the correct encoding type.  Platform default will be used instead, yet this conflicts with the response headers.
> The solution to this is to patch org.apache.struts2.json.JSONUtil.java, line 237, to add the missing encoding parameter from the json.getBytes() call
>                 out = new GZIPOutputStream(response.getOutputStream());
> -->              in = new ByteArrayInputStream(json.getBytes(serializationParams.getEncoding()));
>                 byte[] buf = new byte[1024];

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.