struts 2-json-pluginにおけるGZIP圧縮中国語文字化けし問題の解決


struts 2のstruts 2-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