JAVA编码问题记录

一,在web开发中,比较常遇到的就是get post乱码问题

解决方案:

1,get请求时,参数会得到乱码主要原因取决与当前浏览器的页面是怎么编码,如假设是UTF-8编码,在浏览器地址栏请求时,浏览器会对url进行URLEncoder.encode(url, "utf-8")进行编码,然后相对应的服务器,会根据后台配置

 

tomcat参数串的编码是根据contentType里面的值进行编码的

 

如:tomcat

 

URIEncoding

This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.

useBodyEncodingForURI

This specifies if the encoding specified in contentType should be used for URI query parameters, instead of using the URIEncoding. This setting is present for compatibility with Tomcat 4.1.x, where the encoding specified in the contentType, or explicitly set using Request.setCharacterEncoding method was also used for the parameters from the URL. The default value is  false .

如果http请求中,在contentType中指定了编码方式,那么将采用contentType的编码方式去解码url之后的查询参数,将忽略URIEncoding的配置.

所以在get请求时,如果contentType指定了编码方式,将会带来一定的问题(最大的问题就是,服务器端对查询字符串的编码方式无法统一),最后我决定让 useBodyEncodingForURI 参数保持默认(false):即所有的URL查询字符串的编码采用URIEncoding的参数(UTF-8),服务器端编码保持原来的统一方式.

 

<Connector port="8080" maxThread="50" minSpareThreads="25" maxSpareThread="75" 
enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" 
connectionTimeout="20000" disableUploadTimeout="true"   URIEncoding="utf-8"/>
 

 进行相应的decode而达到编码的一致性,所以如果两者不一致,就会出现乱码问题

 

     2,post请求,只要写个对应的过滤器,就可解决乱码问题

 

if (this.encoding != null && request.getCharacterEncoding() == null){
			
	request.setCharacterEncoding(this.encoding);
}
		
filterChain.doFilter(request, response);

 http post时会对表单值进行encode,服务端会进行decode

 

二,要解决乱码问题,就要达到一整个流程用的都是统一编码,

    1,从页面开始,设置content-type告诉浏览器用怎么编码进行查看

 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

 

   2,进入后台操作时有有相应的以上get post的请求设置,获取参数一般不会出现乱码 ,而后在返回值时,

response.setContentType("text/html;charset=utf-8");告诉浏览器用怎么进行编码查看响应值

 

三,问题汇总:

 

   1,在开发17173搜索时,由于旧的搜索用的是GBK编码,故其他17173系统在调用搜索数据以及搜索时都是用GBK进行查找。

   2,新的搜索采用的是UTF-8编码,故就不兼容旧的其他的系统的查找。解决方案是重新对旧系统进行规划,把其他系统搜索过来的数据用一套GBK编码的格式的页面进行接收keyword,然后对keyword=URLEncoder.encode(keyword, "utf-8");进行编码,再跳转到utf-8的页面去,进行兼容

 

  3,new String(keyword.getBytes("UTF-8"),"GBK")时,遇到两个字的中文字可以进行强制编码成功,三个字的中文字会出现乱码

 

 

public static void main(String[] args) throws UnsupportedEncodingException {
		// 给定某3个汉字
		String src = "你好啊";
		//String src="一二三";
		// 浏览器进行gbk编码,并传送到服务器
		byte[] bytes1 = src.getBytes("utf-8");
		System.out.println(bytes1.length);// 9
		for (int i = 0; i < bytes1.length; i++) {
			System.out.print(bytes1[i] & 0xff);
			System.out.print("\t");
		}

		// tomcat以gbk方式解码(这个片段的说明仅针对gbk处理汉字的情况)
		// 如果一对汉字字节不符合gbk编码规范,则每个字节使用'?'(ascii 63)代替
		// 万幸的话,只是最后一个(第9个)字节因不能成对,变成问号(比如当src="你好啊"时)
		// 不幸的话,中间某些字节就通不过gbk编码规范出现'?'了(比如当src="一二三"时)
		// 总之temp的最后一位必定是问号'?'
		String temp = new String(bytes1, "gbk");

		// 你的action中的代码
		// 由于以上的tomcat以gbk解释utf-8不能成功
		// 所以此时bytes2和bytes1不一样
		byte[] bytes2 = temp.getBytes("gbk");
		System.out.println(bytes2.length);
	
		System.out.println();
		for (int i = 0; i < bytes2.length; i++) {
			System.out.print(bytes2[i] & 0xff);
			System.out.print("\t");
		}
		System.out.println();

		// 构建出来的dest自然不是原先的src
		String dest = new String(bytes2, "utf-8");
		System.out.println(dest);
	}

 

   4, 在编码未确定的情况下,要先检查该中文是属性于哪一种编码

 

 

    public static String getEncoding(String str) {  
        String encode = "ISO-8859-1";  
        try {  
            if (str.equals(new String(str.getBytes(encode), encode))) {  
                String s1 = encode;  
                return s1;  
            }  
        } catch (Exception exception1) {  
        }  
        encode = "UTF-8";
        try {  
            if (str.equals(new String(str.getBytes(encode), encode))) {  
                String s2 = encode;  
                return s2;  
            }  
        } catch (Exception exception2) {  
        }  
        encode = "GBK";  
        try {  
            if (str.equals(new String(str.getBytes(encode), encode))) {  
                String s3 = encode;  
                return s3;  
            }  
        } catch (Exception exception3) {  
        }  
        return "";  
    }  

 然后根据对应的编码new String(str.getBytes(encode), encode)进行转换,而达到编码转换的目的

 

 

 

5,jdk系统编码,Charset.defaultCharset() 这个获取,而这个的信息就与eclipse页面右键属性中更改其编码方式

 

System.out.println(Charset.defaultCharset());  
		String s="中国";
System.out.println(getEncoding(s));

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自wuquanyin1011.iteye.com/blog/1645356