`

web开发中的中文问题

    博客分类:
  • java
 
阅读更多

 

 

web开发中的中文问题

 

jetty处理的总结

http://docs.codehaus.org/display/JETTY/International+Characters+and+Character+Encodings

 

结论:

 

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Properties;

/**
 * 结论:在使用页面编码为gbk时:<br>
 * get时:ajax提交:firefox.ajax.get使用URLEncode(utf8)(但存在bug,见下),ie使用String.getByte(
 * 页面编码).注:此时charset不可信<br>
 * get时:form提交:ie,firefox使用页面编码(当前为gbk).注:此时charset没数据<br>
 * post时:ajax提交:ajax提交firefox、ie使用String.getByte(utf8)编码.注:此时charset不可信<br>
 * post时:表单提交:使用页面编码.注:此时charset没数据<br>
 * 
 * firefox.ajax.post请求,在context-type的charset会自动设置为utf-8,无论你写什么。后台拿数据则通过utf-8
 * 取得正确数据 ie.ajax.post请求,在context-type不设置情况下,后台拿默认charset(gbk)时解析出错。
 * 
 * 问题: 默认URIEncode使用ISO-8859-1,如何得到正确中文?: 答:自行将取出String.getByte(ISO-8859-1),再new
 * String(gbk)<br>
 * 
 * jetty默认对uri使用utf8编码,如果希望其他编码方式,在jetty启动时设置:-Dorg.mortbay.util.URI.charset=gbk
 * tomcat默认对uri使用iso-8859-1编码,如果希望其他编码,配置connector的URIEncoding=gbk
 * 
 * 问题: firefox为什么在页面编码gbk下ajax.post可行而ie不行?
 * 答:firefox下ajax.post传输的是utf-8,context-type中charset不允许用户修改,就算用户设置了,仍为utf-8
 * ie下ajax.post传输的是utf-8,但是context-type的charset允许设置或默认按页面编码,如果页面编码是gbk就出错了。
 * 
 * firefox.ajax.get的bug情况:
 * firefox默认情况是按URLEncode(utf8)的,但是如果下拉框默认有数据,则按页面编码gbk发送,此时charset不可信
 * 
 * 
 * 
 * @author W_jiangyongyuan
 * 
 */
public class Test {
	public static void main(String[] args) throws UnsupportedEncodingException {
		Test t = new Test();
		// t.utf8_ajax_post();
		// t.utf8_form_get_post();
		// t.get_ajax_gbk_firefox();
//		t.get_ajax_gbk_ie();
//		t.change_charset();
//		t.change_charset2();
		t.change_charset3();
//		t.change_charset4();
	}

	String s = "中高风险";

	/**
	 * ie下ajax.get按页面编码,不使用charset
	 * 
	 * @throws UnsupportedEncodingException
	 */
	void get_ajax_gbk_ie() throws UnsupportedEncodingException {
		String value = new String(s.getBytes("UTF-8"), "GBK");// 传输了utf8,转成gbk,firebug界面看到的乱码
		String value2 = new String(URLEncoder.encode(s, "GBK")
				.getBytes("UTF-8"));// 传输了utf8,转成gbk,firebug界面看到的乱码
		System.out.println(value2);
	}

	/**
	 * firefox下ajax.get按charset编码,通过URLEncode(charset)调用
	 * 
	 * @throws UnsupportedEncodingException
	 */
	void get_ajax_gbk_firefox() throws UnsupportedEncodingException {
		System.out.println(URLEncoder.encode(s, "UTF8"));// %D6%D0%CE%C4
	}

	/**
	 * form点击按钮提交,编码按页面编码并通过URLEncodeer提交。
	 * get,post一致,ie,firefox一致,URLEncoder(gbk)
	 * 
	 * @throws UnsupportedEncodingException
	 */
	void utf8_form_get_post() throws UnsupportedEncodingException {
		System.out.println(URLEncoder.encode("中文", "GBK"));// %D6%D0%CE%C4
	}

	/**
	 * ajax.post方式,全部用utf8编码,无论是否设置了context-type中的charset为其他数据<br>
	 * ie,firefox一致,String.getByte("utf-8")
	 * 
	 * @throws UnsupportedEncodingException
	 */
	void utf8_ajax_post() throws UnsupportedEncodingException {
		System.out.println("test utf8 post");
		String value = new String(s.getBytes("UTF-8"), "GBK");// 传输了utf8,转成gbk,firebug界面看到的乱码
		System.out.println(value);
	}

	/**
	 * utf-8错误转成gbk后可能可以正确转回,当字符为2的倍数时。因为utf-8码中文为三个字符
	 * @throws UnsupportedEncodingException
	 */
	void change_charset2() throws UnsupportedEncodingException {
		String s = "中文";
		printByte("utf-8", s);
		String s2 = new String(s.getBytes("utf-8"), "gbk");
		printByte("gbk", s2);
		String s3 = new String(s2.getBytes("gbk"), "utf-8");
		printByte("utf-8", s3);
//如果s只有一个字符,则无法转回
	}

	/**
	 * gbk错误转成utf8后无法正确转回
	 * @throws UnsupportedEncodingException
	 */
	void change_charset3() throws UnsupportedEncodingException {
		String s = "中文";
		printByte("gbk", s);
		String s2 = new String(s.getBytes("gbk"), "utf-8");
		printByte("utf-8", s2);
		String s3 = new String(s2.getBytes("utf-8"), "gbk");
		printByte("gbk", s3);
		System.out.println(s3);
	}

	/**
	 * gbk数据错误转成iso-8859-1后可以正确转回gbk
	 * @throws UnsupportedEncodingException
	 */
	void change_charset4() throws UnsupportedEncodingException {
		String s = "中文";
		printByte("gbk", s);
		String s2 = new String(s.getBytes("gbk"), "iso-8859-1");
		printByte("iso-8859-1", s2);
		String s3 = new String(s2.getBytes("iso-8859-1"), "gbk");
		printByte("gbk", s3);
	}
	

	void printByte(String charset, String s2)
			throws UnsupportedEncodingException {
		System.out.println(s2);
		System.out.println("\nnow is " + charset);
		for (Byte b : s2.getBytes(charset)) {
			System.out.print(Integer.toHexString(b));
		}
		System.out.println("\n");
	}
}

 

上面代码中的change_charset中,测试证明

对于错误转码的情况,将gbk码的字符错误当成utf-8后,无法恢复gbk.因为byte数据已经改变。

而iso-8859和gbk时却不会改变乱码的byte数据。

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics