《Java乱码问题解决方案.doc》由会员分享,可在线阅读,更多相关《Java乱码问题解决方案.doc(16页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Java乱码问题解决方案.txt生活是一张千疮百孔的网,它把所有激情的水都漏光了。寂寞就是你说话时没人在听,有人在听时你却没话说了!Java乱码问题解决方案Java乱码问题一直是困扰初学者的一个难题,下面就根据笔者的经验来给大家一个解决方案。我写了一个Demo的web应用,解决了乱码问题,点击下载1 问题来源 Java的乱码问题,根源在于操作系统、数据库(MySQL)、Web服务器(Tomcat)、页面(JSP)中的编码不一致造成的。例如,mysql的编码是latin1,而页面上字符的编码是GBK,则就会出现乱码问题。2 解决方案 了解了乱码产生的原因,下面就来看一下如何解决乱码。事实上,只要
2、保证各个环节的编码一致,就不会产生乱码,所以只要将所有的环节,设置的编码为UTF-8,就不会出现乱码了(为了支持国际化,建议统一设置成UTF-8)。3 mysql数据库编码的设置(以MySQL 5.0.41为例)? 查看数据库支持的编码:show character set;这样可以查看mysql数据库支持的所有编码,其中可以看到有支持utf8编码。mysql show character set ;+-+-+-+-+| Charset | Description | Default collation | Maxlen |+-+-+-+-+| big5 | Big5 Traditional
3、Chinese | big5_chinese_ci | 2 | dec8 | DEC West European | dec8_swedish_ci | 1 | cp850 | DOS West European | cp850_general_ci | 1 | hp8 | HP West European | hp8_english_ci | 1 | koi8r | KOI8-R Relcom Russian | koi8r_general_ci | 1 | latin1 | cp1252 West European | latin1_swedish_ci | 1 | latin2 | IS
4、O 8859-2 Central European | latin2_general_ci | 1 | swe7 | 7bit Swedish | swe7_swedish_ci | 1 | ascii | US ASCII | ascii_general_ci | 1 | ujis | EUC-JP Japanese | ujis_japanese_ci | 3 | sjis | Shift-JIS Japanese | sjis_japanese_ci | 2 | hebrew | ISO 8859-8 Hebrew | hebrew_general_ci | 1 | tis620 | T
5、IS620 Thai | tis620_thai_ci | 1 | euckr | EUC-KR Korean | euckr_korean_ci | 2 | koi8u | KOI8-U Ukrainian | koi8u_general_ci | 1 | gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci | 2 | greek | ISO 8859-7 Greek | greek_general_ci | 1 | cp1250 | Windows Central European | cp1250_general_ci | 1 |
6、 gbk | GBK Simplified Chinese | gbk_chinese_ci | 2 | latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 | armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | 1 | utf8 | UTF-8 Unicode | utf8_general_ci | 3 | ucs2 | UCS-2 Unicode | ucs2_general_ci | 2 | cp866 | DOS Russian | cp866_general_ci | 1 |
7、keybcs2 | DOS Kamenicky Czech-Slovak | keybcs2_general_ci | 1 | macce | Mac Central European | macce_general_ci | 1 | macroman | Mac West European | macroman_general_ci | 1 | cp852 | DOS Central European | cp852_general_ci | 1 | latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 | cp1251 | Windows
8、Cyrillic | cp1251_general_ci | 1 | cp1256 | Windows Arabic | cp1256_general_ci | 1 | cp1257 | Windows Baltic | cp1257_general_ci | 1 | binary | Binary pseudo charset | binary | 1 | geostd8 | GEOSTD8 Georgian | geostd8_general_ci | 1 | cp932 | SJIS for Windows Japanese | cp932_japanese_ci | 2 | eucjp
9、ms | UJIS for Windows Japanese | eucjpms_japanese_ci | 3 |+-+-+-+-+36 rows in set (0.00 sec)? 查看数据库默认的编码: show variables like %character%;mysql show variables like %character%;+-+-+| Variable_name | Value |+-+-+| character_set_client | latin1 | character_set_connection | latin1 | character_set_datab
10、ase | latin1 | character_set_filesystem | binary | character_set_results | latin1 | character_set_server | latin1 | character_set_system | utf8 | character_sets_dir | E:mysql-5.0.41-win32sharecharsets |+-+-+8 rows in set (0.00 sec)可以看到,mysql数据库中,此时有关字符串的设置的参数,其中“character_set_server”为创建数据库是默认的编码,现在需
11、要将其修改为utf8。? 修改数据库默认的编码:set character_set_server=utf8;mysql set character_set_server=utf8;Query OK, 0 rows affected (0.00 sec) 执行改命令后,可以看到数据库此时的默认编码改为utf8了mysql show variables like %character%;+-+-+| Variable_name | Value |+-+-+| character_set_client | latin1 | character_set_connection | latin1 | ch
12、aracter_set_database | latin1 | character_set_filesystem | binary | character_set_results | latin1 | character_set_server | utf8 | character_set_system | utf8 | character_sets_dir | E:mysql-5.0.41-win32sharecharsets |+-+-+8 rows in set (0.00 sec) 此时,创建数据库和表如果不指定字符集,则也会使用uft8的编码了。? 查看schema和table编码:s
13、how create database 数据库名; show create table 表名;例如存在这样一个数据库mydbdefault,mydbdefault中有一个表testmysql use mydbdefault;Database changedmysql show create database mydbdefault;+-+-+| Database | Create Database |+-+-+| mydbdefault | CREATE DATABASE mydbdefault /*!40100 DEFAULT CHARACTER SET latin1 */ |+-+-+1
14、row in set (0.00 sec)数据库mydbdefault的编码为latin1mysql show create table test;+-+-+| Table | Create Table |+-+-+| test | CREATE TABLE test ( id int(20) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1 |+-+-+1 row in set (0.00 sec)表的编码为latin1? 修改schema和table编码:alter database 数据库名 character set utf8;alt
15、er table 表名 character set utf8;既然查出数据库和表的编码都不是uft8,所以此时要将数据库和表的字符集改成utf8。mysql alter database mydbdefault character set utf8;Query OK, 1 row affected (0.00 sec) mysql show create database mydbdefault;+-+-+| Database | Create Database |+-+-+| mydbdefault | CREATE DATABASE mydbdefault /*!40100 DEFAULT
16、 CHARACTER SET utf8 */ |+-+-+1 row in set (0.00 sec) mysql alter table test character set utf8;Query OK, 0 rows affected (0.03 sec)Records: 0 Duplicates: 0 Warnings: 0 mysql show create table test;+-+-+| Table | Create Table |+-+-+| test | CREATE TABLE test ( id int(20) default NULL) ENGINE=MyISAM D
17、EFAULT CHARSET=utf8 |+-+-+1 row in set (0.00 sec)? 在不知道默认的编码方式的情况下,创建数据库和表时,最好指定字符编码为utf8:? create database 数据库名 character set utf8;create table 表名 (.) character set utf8;有关mysql的字符集的命令,可以mysql的参考手册4 Tomcat编码的设置(以Tomcat 6.0.14版本为例)在Tomcat的安装目录下,找到TOMCAT_HOMEconfserver.xml,然后找到以下代码,在其后加上URIEncoding=U
18、TF-8 5 web应用中编码处理 在web应用中,为了确保提交的字符串为uft-8的,可以编写一个过滤器filter,过滤器的在web.xml中的配置如下:对应的SetCharacterEncodingFilter类代码如下: Set Character Encoding com.fengmanfei.util.SetCharacterEncodingFilter encoding UTF-8 Set Character Encoding /* 过滤器的代码如下所示:package com.fengmanfei.util; import java.io.IOException; import
19、 javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse; public class SetCharacterEncodingFilter implements Filter private String encoding = UTF-8; public v
20、oid doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException request.setCharacterEncoding(encoding); chain.doFilter(request, response); public void init(FilterConfig filterConfig) throws ServletException String s = filterConfig.getInitParamet
21、er(encoding); if (s != null) encoding = s; public void destroy() 其中,关键的是通过过滤器,将request请求设置UTF-8编码 6 数据库连接URLjdbc:mysql:/localhost:3306/mydb?characterEncoding=UTF-87 页面中编码处理在jsp页面上,同时也要设置页面编码方式8 Eclipse中编码的设置 最后,在使用Eclipse时,要将工作区的编码也设置为UTF-8,选择“Window”|“Preference”|“General”|“Workspace”,将Text file en
22、codeing 改为UTF-8,Java/JSP中文乱码问题解决心得自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。一、Java中文问题的由来 Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程中,
23、使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写的话,尽量手动带参数ecoding GBK或ecoding gb2312编译;对于JSP,在文件头加上或基本上就能解决这类乱码问题。本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:从页面form提交数据到java程序 bytechar从java程序到页面显示 char
24、byte从数据库到java程序 bytechar从java程序到数据库 charbyte从文件到java程序 bytechar从java程序到文件 charbyte从流到java程序 bytechar从java程序到流 charbyte如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。二、解决方法 前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。1、JSP与页面参数之间的乱码 J
25、SP获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding(GBK)或request.setCharacterEncoding(gb2312)。如果在JSP将变量输出到页面时出现了乱码,可以通过设置response.setContentType(text/html;charset=GBK)或response.setContentType(text/html;charset=gb2312)解决。
26、如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:web.xml:CharacterEncodingFilternet.vschool.web.CharacterEncodingFilterencodingGBKCharacterEncodingFilter/*CharacterEncodingFilter.java:public class CharacterEncodingFilter implements Filter protected String encoding = null; publ
27、ic void init(FilterConfig filterConfig) throws ServletException this.encoding = filterConfig.getInitParameter(encoding);public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException request.setCharacterEncoding(encoding);response.setCo
28、ntentType(text/html;charset=+encoding);chain.doFilter(request, response);2、Java与数据库之间的乱码 大部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的mysql驱动:jdbc:mysql:/localhost/WEBCLDB?useUnicode=true&characterEncodi
29、ng=GBK。3、Java与文件/流之间的乱码 Java读写文件最常用的类是FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。在这种情况下,建议使用FileReader和FileWriter的父类:InputStreamReader/Ou
30、tputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类型:InputStreamReader(InputStream in, Charset cs) 和OutputStreamWriter(OutputStream out, Charset cs)。 4、其他 上面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组件上传文件,上传文件
31、同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性charset和setCharset(String)方法,将upload()方法中提取参数语句:String value = new String(m_binArray, m_startData, (m_endData - m_startD