首页 > 范文大全 > 正文

基于java web中文乱码问题的研究

开篇:润墨网以专业的文秘视角,为您筛选了一篇基于java web中文乱码问题的研究范文,如需获取更多写作素材,在线客服老师一对一协助。欢迎您的阅读与分享!

【摘要】在Java web编程中,经常会碰到汉字的处理及显示问题,以不小心就会产生一大堆乱码或者问号。造成这种问题的根本原因是Java中默认的编码方式是Unicode,而中国人通常使用的文件和DB都是基于GB2312或BIG5等编码,故会出现此问题。本文首先详细分析这些中文乱码问题产生的原因,最后在此基础上提出详细合理的解决方案。

【关键词】java web;乱码;编码;方案

1.引言

为了能在计算机中表示不同语言中字符,每个国家(或区域)都规定了计算机信息交换用的字符编码集,如美国的ASCII,中国GB2312和GBK,日本的JIS等。Java语言内部用Unicode来表示字符,Unicode被称为统一的字符编码标准集,它为几乎每种语言中的字符设定了唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。这也使得Java具有良好的可移植性,符合其国际化的思想。

然而在实际应用中,由于应用程序的运行环境不同,和各个本地字符集的补充、完善,以及系统或应用程序实现的不规范,转码时出现的中文乱码问题时时困扰着程序员和用户。

2.中文乱码产生的原因

J2EE应用程序是运行在J2EE容器中。在这个系统中,输入途径有很多种:一种是通过页面表单打包成请求(request)发往服务器的;第二种是通过数据库读入;还有第3种输入比较复杂,JSP在第一次运行时总是被编译成Servlet,JSP中常常包含中文字符,那么编译使用javac时,Java将根据默认的操作系统编码作为初始编码。除非特别指定,如在Jbuilder/eclipse中可以指定默认的字符集。 输出途径也有几种:第一种是JSP页面的输出。由于JSP页面已经被编译成Servlet,那么在输出时,也将根据操作系统的默认编码来选择输出编码,除非指定输出编码方式;还有输出途径是数据库,将字符串输出到数据库。

由此看来,一个J2EE系统的输入输出是非常复杂,而且是动态变化的,而Java是跨平台运行的,在实际编译和运行中,都可能涉及到不同的操作系统,如果任由Java自由根据操作系统来决定输入输出的编码字符集,这将不可控制地出现乱码。

在Web应用中,通常都包括了浏览器、Web服务器、Web应用程序和数据库等部分。若不指定编码格式,浏览器会根据本地系统默认的字符集(如:GB2312)提交数据,而Web容器默认采用的是ISO-8859-1的编码方式解析Post数据,另外JDBC驱动程序多数也采用ISO-8859-1的编码方式,因此,在Web应用程序运行过程中,输入的中文字符往往需要在不同的字符集之间来回转换,这就导致了中文乱码问题的频繁出现。

3.中文乱码问题分类和解决方案

3.1 中文展现的乱码问题

每一个文件(java,js,jsp,html等)都有其本身的编码格式,文件中的代码在一种编码中显示正常,在另外一种编码下就会显示出乱码。在Eclipse中,每一个工程都会有编码格式(Text file encoding), 一般默认为GBK。而一个比较好的编程习惯是新建一个项目,优先把项目的编码设为UTF-8即<%@ page language=”java” pageEncoding=”UTF-8”>。这样做的原因很简单,UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。几种常见的字符集,GBK,GB2312,UTF-8之间的关系如下:GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换。

3.2 中文写入数据库乱码问题

Java采用Unicode码编码方式,中英文字符均采用16bit存储。既然存储英文信息是正确的,根据一定规则,将中文信息转换成英文信息后存储,自然不会出现乱码现象。读取信息时再进行逆向操作,将英文信息还原成中文信息即可。由GB2312编码规则可知,汉字一般为二个高位为1的ASCII码,在转换时将一个汉字的二个高位1去掉,还原时再将二个高位1加上。为了处理含有英文字符的中文字串,对英文字符则需要加上一个Byte 0标记。以下提供的一个公用静态方法,可加入任何一个类中使用。将中英文字串转换成纯英文字串

public static String toTureAsciiStr (String str){

StringBuffer= new String Buffer();

byte[] bt = str.getBytes();

for(int i =0 ;i〈bt.length;i++){

if(bt[i]〈0){

//是汉字去高位1

sb.append((char)(bt[i]&&0x7f));

}else{//是英文字符 补0作记录

sb.append((char)0);

sb.append((char)bt[i]);

}

}

return sb.toString();}

3.3 参数传递的乱码问题

(1)Get方法的情况

Get方法的时候主要是URL传递中文。

如果是在js文件中,可以使用如下代码进行中文转码。

Js代码

var url =”http:///s?industry=编码”

url = encodeURI(url);

如果是在jsp文件中,则可以使用如下语句进行转码。

页面开始引入:

Java代码

<%@ page import=”.URLEncoder” %>

需要转码的地方使用URLEncoder进行编码:

Js代码

<a href=”xxxxx.xx?industry=<%= URLEncoder.encode(“http:///s?wd=编码”, “UTF-8”)%>”>

无论使用哪种方法,在后台获取中文的时候都要使用如下代码:

Java代码

request.setCharacterEncoding(“utf-8”);

String industry = new String(

request.getParameter(“industry “). getBytes(“ISO8859-1”),”UTF-8”);

(2)POST方法的情况

对于Post的情况,只需要在post的函数调用部分,制定post的header的字符集,如:

Js代码

xmlHttp.open(“post”, url , true);

xmlHttp.setRequestHeader(“Content-Type”,”text/xml; charset= utf-8”);

xmlHttp.send(param);

其中param为要传递的参数。

后台部分和get方法一样,设置如下即可,注意传输和接受的字符集要统一。

3.4 下载文件时乱码

下过下载的人都知道下载的文件容易出现乱码,原因也是没有对输出流的编码格式进行限定。

附上一段代码,用来完成无乱码下载。

HttpServletResponse response = ServletActionContext.getResponse();

response.setContentType("text/html;charset=utf-8”);

response.reset();

String header = “attachment;

filename=” + picName;

header = new String(header.getBytes(), “UTF-8”);

response.setHeader(“Content-disposition”, header);

核心代码就上几句,注意第二句和第三句的reset的顺序不能搞错。reset的作用是用来清空buffer缓存的,清空请求前部的一些空白行。

4.总结

在处理java的编码问题时,要分清楚三个概念:Java采用的编码:unicode,JVM平台默认字符集和外部资源的编码。 虽然问题产生的原因多种多样,然而只要我们理解了字符编码的转换过程,仔细分析乱码产生的原因,找到问题的关键,就能对症下药,解决问题。不过,随着中文字符集的变化,不仅仅是Java编程,中文信息处理中的问题还是会存在一段时间的。在项目中尽量把编码统一为UTF-8。

参考文献

[1]贾蓓,镇明敏,杜磊.Java Web整合开发实战[M].北京:清华大学出版社,2013:158-161.

[2]孙鑫.Java Web开发详解[M].北京:电子工业出版社,2012:616-617.

[3]耿祥义,张跃平.JSP实用教程[M].北京:清华大学出版社,2009:36-37.

[4]李刚.轻量级JavaEE企业应用实战[M].北京:电子工业出版社,2012:500-510.