Java中文问题一直困扰着很多初学者,如果了解了Java系统的中文问题原理,我们就可以对中文问题能够采取根本的解决之道。 最古老的解决方案是使用String的字节码转换,这种方案问题是不方便,我们需要破坏对象封装性,进行字节码转换。
还有一种方式是对J2EE容器进行编码设置,如果J2EE应用系统脱离该容器,则会发生乱码,而且指定容器配置不符合J2EE应用和容器分离的原则。
在Java内部运算中,涉及到的所有字符串都会被转化为UTF-8编码来进行运算。那么,在被Java转化之前,字符串是什么样的字符集? Java总是根据操作系统的默认编码字符集来决定字符串的初始编码,而且Java系统的输入和输出的都是采取操作系统的默认编码。
因此,如果能统一Java系统的输入、输出和操作系统3者的编码字符集合,将能够使Java系统正确处理和显示汉字。这是处理Java系统汉字的一个原则,但是在实际项目中,能够正确抓住和控制住Java系统的输入和输出部分是比较难的。J2EE中,由于涉及到外部浏览器和数据库等,所以中文问题乱码显得非常突出。
J2EE应用程序是运行在J2EE容器中。在这个系统中,输入途径有很多种:一种是通过页面表单打包成请求(request)发往服务器的;第二种是通过数据库读入;还有第3种输入比较复杂,JSP在第一次运行时总是被编译成Servlet,JSP中常常包含中文字符,那么编译使用javac时,Java将根据默认的操作系统编码作为初始编码。除非特别指定,如在Jbuilder/eclipse中可以指定默认的字符集。
输出途径也有几种:第一种是JSP页面的输出。由于JSP页面已经被编译成Servlet,那么在输出时,也将根据操作系统的默认编码来选择输出编码,除非指定输出编码方式;还有输出途径是数据库,将字符串输出到数据库。
由此看来,一个J2EE系统的输入输出是非常复杂,而且是动态变化的,而Java是跨平台运行的,在实际编译和运行中,都可能涉及到不同的操作系统,如果任由Java自由根据操作系统来决定输入输出的编码字符集,这将不可控制地出现乱码。
正是由于Java的跨平台特性,使得字符集问题必须由具体系统来统一解决,所以在一个Java应用系统中,解决中文乱码的根本办法是明确指定整个应用系统统一字符集。
指定统一字符集时,到底是指定ISO8859_1 、GBK还是UTF-8呢?
(1)如统一指定为ISO8859_1,因为目前大多数软件都是西方人编制的,他们默认的字符集就是ISO8859_1,包括操作系统Linux和数据库MySQL等。这样,如果指定Jive统一编码为ISO8859_1,那么就有下面3个环节必须把握:
开发和编译代码时指定字符集为ISO8859_1。
运行操作系统的默认编码必须是ISO8859_1,如Linux。
在JSP头部声明:。
(2)如果统一指定为GBK中文字符集,上述3个环节同样需要做到,不同的是只能运行在默认编码为GBK的操作系统,如中文Windows。
统一编码为ISO8859_1和GBK虽然带来编制代码的方便,但是各自只能在相应的操作系统上运行。但是也破坏了Java跨平台运行的优越性,只在一定范围内行得通。例如,为了使得GBK编码在linux上运行,设置Linux编码为GBK。
那么有没有一种除了应用系统以外不需要进行任何附加设置的中文编码根本解决方案呢?
将Java/J2EE系统的统一编码定义为UTF-8。UTF-8编码是一种兼容所有语言的编码方式,惟一比较麻烦的就是要找到应用系统的所有出入口,然后使用UTF-8去“结扎”它。
一个J2EE应用系统需要做下列几步工作:
- 开发和编译代码时指定字符集为UTF-8。JBuilder和Eclipse都可以在项目属性中设置。
- 使用过滤器,如果所有请求都经过一个Servlet控制分配器,那么使用Servlet的filter执行语句,将所有来自浏览器的请求(request)转换为UTF-8,因为浏览器发过来的请求包根据浏览器所在的操作系统编码,可能是各种形式编码。关键一句:
request.setCharacterEncoding(”UTF-8″)。
网上有此filter的源码,Jdon框架源码中com.jdon.util.SetCharacterEncodingFilter
需要配置web.xml 激活该Filter。
- 在JSP头部声明:。
- 在Jsp的html代码中,声明UTF-8:
- 设定数据库连接方式是UTF-8。例如连接MYSQL时配置URL如下:
jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
注意,上述写法是JBoss的mysql-ds.xml写法,多亏网友提示,在tomcat中&要写成&即可。一般其他数据库都可以通过管理设置设定UTF-8
- 其他和外界交互时能够设定编码时就设定UTF-8,例如读取文件,操作XML等。
笔者以前在Jsp/Servlet时就采取这个原则,后来使用Struts、Tapestry、EJB、Hibernate、Jdon等框架时,从未被乱码困扰过,可以说适合各种架构。希望本方案供更多初学者分享,减少Java/J2EE的第一个拦路虎,也避免因为采取一些临时解决方案,导致中文问题一直出现在新的技术架构中。
另一篇文章
对于一个Java初学者来说,经常碰到的一个问题恐怕就是中文问题了。其实很正常,我们有几千年的悠久历史嘛,博大精深,岂能是小小的计算机语言所能包容的?呵呵,开个玩笑。但是不可否认的一个事实就是,就算是一个比较有经验的开发人员,也经常面对着屏幕上的乱码而大伤脑筋。
想究其原因、彻底解决这一问题吗?follow me……
乱码原因
java内核是unicode的。但Java总是根据操作系统的默认编码字符集来决定字符串的初始编码,而且Java系统的输入和输出的都是采取操作系统的默认编码,而数据库、文件、网络传输中的字节流……采用的编码更是各不相同。所以不可避免的就会出现烦人的乱码问题了。
解决办法
1、GB2312、GBK、Unicode(UTF8)?
从字符集的大小比较 GB2312 < GBK < UTF8,很显然,如果我们采用UTF8作为系统编码的话,是不会有错的。而且如果你要考虑国际化的话,UTF8似乎是你唯一的选择
2、开发和编译代码时指定字符集为UTF-8
JBuilder和Eclipse都可以在项目属性中设置。
3、使用过滤器
编写过滤器
package com.javer.test.language;
import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse;
/** * <p>Title: EncodingFilter</p> * @author javer(QQ:84831612) * @version 1.0 * @link http://blog.csdn.net/java008 */ public class EncodingFilter implements Filter { FilterConfig config;
public void init(FilterConfig parm1) throws javax.servlet.ServletException { this.config = parm1; }
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws java.io.IOException, javax.servlet.ServletException { if (req.getCharacterEncoding() == null || !req.getCharacterEncoding().equals("UTF-8")) { req.setCharacterEncoding("UTF-8"); } chain.doFilter(req, res); }
public void destroy() { this.config = null; } } |
在web.xml文件中配置该过滤器
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>javer‘s project</display-name> <filter> <filter-name>EncodingFilter</filter-name> <display-name>EncodingFilter</display-name> <description>对编码进行转换</description> <filter-class>com.javer.test.language.EncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> |
4、在JSP 中进行声明
在JSP头部声明<%@ page contentType="text/html;charset= UTF-8" %>
在Jsp的html代码中声明<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5、数据库管理
一般数据库都可以通过管理设置设定UTF-8
也可以通过jdbc链接时指定编码参数,如:mysql:jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
6、其它
其他所有和外界交互时能够设定编码时就设定UTF-8,例如读取文件,操作XML等。总之,记住一个原则:在所有系统的出入口处都用UTF8编码进行“翻译”!
posted on 2007-03-23 11:31
有猫相伴的日子 阅读(611)
评论(0) 编辑 收藏 所属分类:
j2ee