`
wu_quanyin
  • 浏览: 204404 次
  • 性别: Icon_minigender_1
  • 来自: 福建省
社区版块
存档分类
最新评论

JAVA编码问题记录

    博客分类:
  • J2SE
阅读更多

一,在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));

 

 

 

 

 

 

 

 

 

 

3
5
分享到:
评论
2 楼 wyzxzws 2012-08-21  
小鸟学习了!
1 楼 xiaotao.2010 2012-08-21  
写的不错!
弱弱说一句 建议使用URL二次转码, 这样可以避免 服务器和浏览器的编码不同意的问题!
效果比URL一次转码要好!

相关推荐

    Java出圈问题编码(记录出圈人的先后顺序)

    Java出圈问题编码,500人,每隔两人就出圈,记录每个人出圈的顺序。

    java做的一下记录本

    这是我用Java 写的一个用于记录上班下班记录的小软件. 还有留言功能哦. 写入的文件是用streamoutOpject,直接打开是会显示的是一些乱码哦.

    基于java的货物进销管理系统

    编写一个Inventory.java完成以下功能(没有学过Java文件处理之前,各位同学可以使用硬编码将数据放进两个Vector变量里。等学过Java文件处理之后,再补充数据文件读取部分): 1.程序首先打开并读取Inventory.txt中...

    霍夫曼编码与解码的Java实现

    huffman的java实现 码表生成程序 可对任意“.txt”文件进行概率统计,显示字符及其概率对照表; 依概率编制Huffman码表,显示字符、对应概率及码字对照表。 编码程序 使用码表,对任意“.txt”进行Huffman编码; ...

    mysql插入记录防止乱码

    mysql插入记录防止乱码,这是我在编程时通过网上下载来的资料,解决了我用VFP或者JAVA插入记录的问题。

    实体属性变更历史记录框架-变更历史记录从此无忧

    4.实体属性变化前后的值需要把编码转成有意义的文字.例如:实体类中性别用 0,1表示,而希望变更历史中记录前后变化的值是"男","女". 5.传入实体对象自动识别实体Id,而不需要手工传入. 6.实体的属性名不好记,想加一个好...

    JAVA上百实例源码以及开源项目

    通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥,通常应对私钥加密后再保存、如何从...

    java安全编码规范

    java安全编码规范-英文版,关注安全的同学可以学习一下

    JAVA上百实例源码以及开源项目源代码

    通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥,通常应对私钥加密后再保存、如何从...

    Java经典编程规范,参考京东和华为的Java编程规范标准,将两家公司共同拥有的规范提取并整理得出,值得收藏

    本文档从“Java编程代码规范”,“Java编程注释规范”,“Java编程命名规范”,“代码缩进/断行/空行/空格/大括号规范”,“日志记录规范”和“代码上库规范”六个方面提取两家公司的Java编程规范共性。希望能供Java...

    java连接AmericanascII7字符集oracle例子

    java连接AmericanascII7字符集oracle例子

    java编码规范

    java编码规范

    java开源包11

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包6

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包9

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    java开源包101

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    JAVA实战项目源码-计算机毕业设计SSM项目java专业-java进销存管理系统(jsp+mysql)

    JAVA实战项目源码-计算机毕业设计SSM项目java专业-java进销存管理系统(jsp+mysql) 软件分前台收银和收台管理两大部分: 前台可对不同会员卡产生不同的折扣率,前台涉及三张数据库表的操作: 商品表—用来查找相应的...

    java开源包4

    一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...

    Java-JDBC【源码】数据库连接池技术、常规操作与Durid对比、测试(20-200)不同连接数下,10万记录,1万并发

    Java-JDBC【源码】数据库连接池技术、常规操作与Durid对比、测试(20-200)不同连接数下,10万记录,1万并发,CPU磁盘占用情况 1.数据库连接池 2.Durid介绍(官方文档) 3.编码,问题,常规并发操作 3.1.JDBCUtil....

Global site tag (gtag.js) - Google Analytics