??? 当使用struts2的struts2-json-plugin输出接送数据时,如果配置enableGZIP为true,发现竟然有中文乱码问题。查看源代码,果然有一小小问题,所以干脆动手自己修改吧。
?1.首先在struts.xml中加入下面的代码:
<!-- 修正struts2-json-plugin-2.1.8.1中enableGZIP为true时中文乱码问题 --> <package name="json-guofeng" extends="json-default"> <result-types> <result-type name="json" class="com.guofeng.ux.jsonplugin.GfJSONResult"/> </result-types> </package>
?2.GfJSONResult:
public class GfJSONResult extends JSONResult{ /** * @author $Author: GuoFeng $ * @date $Date:Sep 28, 2010 3:39:33 PM $ * 修正struts2-json-plugin-2.1.8.1中enableGZIP为true时中文乱码问题 */ private static final long serialVersionUID = -997525907667125535L; private int statusCode; private int errorCode; private boolean prefix; private String contentType; @Override protected void writeToResponse(HttpServletResponse response, String json, boolean gzip) throws IOException { GfJSONUtil.writeJSONToResponse(new SerializationParams(response, getEncoding(), isWrapWithComments(), json, false, gzip, isNoCache(), statusCode, errorCode, prefix, contentType, getWrapPrefix(), getWrapSuffix())); } public void setStatusCode(int statusCode) { this.statusCode = statusCode; } public void setErrorCode(int errorCode) { this.errorCode = errorCode; } public void setPrefix(boolean prefix) { this.prefix = prefix; } public void setContentType(String contentType) { this.contentType = contentType; } }
?
3.GfJSONUtil代码:
public class GfJSONUtil { private static final Logger LOG = LoggerFactory.getLogger(MyJSONUtil.class); public static void writeJSONToResponse( SerializationParams serializationParams) throws IOException { StringBuilder stringBuilder = new StringBuilder(); if (StringUtils.isNotBlank(serializationParams.getSerializedJSON())) stringBuilder.append(serializationParams.getSerializedJSON()); if (StringUtils.isNotBlank(serializationParams.getWrapPrefix())) stringBuilder.insert(0, serializationParams.getWrapPrefix()); else if (serializationParams.isWrapWithComments()) { stringBuilder.insert(0, "/* "); stringBuilder.append(" */"); } else if (serializationParams.isPrefix()) stringBuilder.insert(0, "{}&& "); if (StringUtils.isNotBlank(serializationParams.getWrapSuffix())) stringBuilder.append(serializationParams.getWrapSuffix()); String json = stringBuilder.toString(); if (LOG.isDebugEnabled()) { LOG.debug("[JSON]" + json); } HttpServletResponse response = serializationParams.getResponse(); // status or error code if (serializationParams.getStatusCode() > 0) response.setStatus(serializationParams.getStatusCode()); else if (serializationParams.getErrorCode() > 0) response.sendError(serializationParams.getErrorCode()); // content type if (serializationParams.isSmd()) response.setContentType("application/json-rpc;charset=" + serializationParams.getEncoding()); else response.setContentType(serializationParams.getContentType() + ";charset=" + serializationParams.getEncoding()); if (serializationParams.isNoCache()) { response.setHeader("Cache-Control", "no-cache"); response.setHeader("Expires", "0"); response.setHeader("Pragma", "No-cache"); } if (serializationParams.isGzip()) { response.addHeader("Content-Encoding", "gzip"); GZIPOutputStream out = null; InputStream in = null; try { out = new GZIPOutputStream(response.getOutputStream()); /** * @author $Author: GuoFeng $ 修正编码问题 * @date $Date:Sep 28, 2010 3:40:17 PM $ */ 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); } } }
?
??? 其实只需要修改一句代码即可:
in = new ByteArrayInputStream(json.getBytes(serializationParams .getEncoding()));
?
?? 在源码中只写了json.getBytes(),也就是取到的本地的编码,即GBK,所以无法与整个项目的UTF-8相匹配。
?
?? 当然,之后要写的所有struts的配置文件,用到json的包都要继承"json-guofeng"了。这样当我们再使用"enableGZIP"=true这个配置时不会再有中文乱码问题。在firebug中查看了一下,大概能压缩json数据40%吧,当然比较大的数据没有尝试……
?? 看到有些文章指出使用GZIP压缩会对服务器性能消耗较大,建议无带宽限制的内网项目中不要使用。
?? 具体内容请看:http://www.iteye.com/topic/171207
1 楼
hanzhenggang
2012-03-26
其实这个没有必要那么麻烦,可以通过配置解决的。
<result type="json" >
<param name="defaultEncoding">gbk</param>
</result>
<result type="json" >
<param name="defaultEncoding">gbk</param>
</result>