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
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.