`
guofengcn
  • 浏览: 51205 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

解决struts2-json-plugin中GZIP压缩中文乱码问题

阅读更多

    当使用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>

相关推荐

Global site tag (gtag.js) - Google Analytics