最基本的三种乱码
1、JSP页面显示乱码
2、表单提交中文时出现乱码
3、数据库连接
大家在JSP的开发过程中,经常出现中文乱码的问题,可能一直困扰着您,我现在把我在JSP开发中遇到的中文乱码的问题及解决办法写出来供大家参考。
1、JSP页面显示乱码
下面的显示页面(display.jsp)就出现乱码:
<html>
<head>
<title>JSP的中文处理</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<%
//这是中文乱码测试中的注释
out.print("JSP的中文处理,使用out.print()");
%>
</body>
</html>
对不同的WEB服务器和不同的JDK版本,处理结果就不一样。
原因:服务器使用的编码方式不同和浏览器对不同的字符显示结果不同而导致的。
解决办法:在JSP页面中指定编码方式(gb2312),即在页面的第一行加上:<%@ page contentType="text/html; charset=gb2312"%>,就可以消除乱码了。完整页面如下:
<%@ page contentType="text/html; charset=gb2312"%>
<html>
<head>
<title>JSP的中文处理</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<%
//这是中文乱码测试中的注释
out.print("JSP的中文处理,使用out.print()");
%>
</body>
</html>
在Tomcat 5.0和jdk1.4.2中测试结果:
当不添加第一行时,页面显示:
添加第一行后,页面显示:
如果将gb2312改为utf-8时,页面显示:
如果使用<%@ page contentType="text/html; charset=UTF-8"%><%@ page pageEncoding="gb2312" %>页面显示:
如果只使用<%@ page pageEncoding="gb2312" %>页面显示:
2、表单提交中文时出现乱码
下面是一个提交页面(submit.jsp),代码如下:
<html>
<head>
<title>JSP的中文处理</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<form name="form1" method="post" action="process.jsp">
<div align="center">
<input type="text" name="name">
<input type="submit" name="Submit" value="Submit">
</div>
</form>
</body>
</html>
下面是处理页面(process.jsp)代码:
<%@ page contentType="text/html; charset=gb2312"%>
<html>
<head>
<title>JSP的中文处理</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<%=request.getParameter("name")%>
</body>
</html>
如果submit.jsp提交英文字符能正确显示,如果提交中文时就会出现乱码。
原因:浏览器默认使用UTF-8编码方式来发送请求,而UTF- 8和GB2312编码方式表示字符时不一样,这样就出现了不能识别字符。
解决办法::通过request.seCharacterEncoding ("gb2312")对请求进行统一编码,就实现了中文的正常显示。修改后的process.jsp代码如下:
<%@ page contentType="text/html; charset=gb2312"%>
<%
request.seCharacterEncoding("gb2312");
%>
<html>
<head>
<title>JSP的中文处理</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<%=request.getParameter("name")%>
</body>
</html>
3、数据库连接出现乱码
只要涉及中文的地方全部是乱码,解决办法:在数据库的数据库URL中加上
useUnicode=true&characterEncoding=GBK 就OK了。
4、数据库的显示乱码
在mysql4.1.0中,varchar类型,text类型就会出现中文乱码,对于varchar类型把它设为binary属性就可以解决中文问题,对于text类型就要用一个编码转换类来处理,实现如下:
public class Convert {
/** 把ISO-8859-1码转换成GB2312
*/
public static String ISOtoGB(String iso){
String gb;
try{
if(iso.equals("") || iso == null){
return "";
}
else{
iso = iso.trim();
gb = new String(iso.getBytes("ISO-8859-1"),"GB2312");
return gb;
}
}
catch(Exception e){
System.err.print("编码转换错误:"+e.getMessage());
return "";
}
}
}
把它编译成class,就可以调用Convert类的静态方法ISOtoGB()来转换编码。
如果你还有什么不懂之处:我给大家推荐一个好的JSP-JAVA网站:
http://www.phy.hbnu.edu.cn/dsp/
总结:
1. 在jsp中<%@ page contentType="text/html; charset=A" %>如果指定了,那么在该jsp中所有构造的String(不是引用),如果?]有指定编码,那么这些String的编码是A的;
从request的得到的String如果?]有指定request的编码的话,他是iso-8859-1的;
从别的地方得到的String是使用原?沓跏嫉谋嗦氲模?比如从数据库得到String,如果数据库的编码是B,那么该String的编码是B而不是A的,也不是系统默认的;
此时,如果要输出的String的编码不是A,那么,很可能显示乱码的,所以首先要将String正确转化为编码A的String,然后输出。
2. 在jsp中<%@ page contentType="text/html; charset=A" %>?]有指定,那么相当于指定了<%@ page contentType="text/html; charset=ISO-8859-1" %>
3. Servelte中如果执行了像 response.setContentType("text/html;charset=A");说明将response的字符输出流编码设置为A,所有要输出的String的编码要转化为A的,否则会得到乱码的。
Servelet中从request得到的String的编码和jsp中一样的,但是在servlet java文件中构造的String是使用的系统默认的编码的。在servelt中从外部得到的String 是使用原来的编码的,比如从编码为B的数据库得到的数据是编码为B的,不是A,也不是系统默认的编码。
其他情况下的乱码:
一、常见乱码问题
注:以下“后台”字眼,相当于在servlet内,或者某一个类内,或者struts的action内。
1.一字符串在后台用system.out.println输出正常,保存在session里到JSP页面显示乱码
原因:似乎是默认的JSP页面采用8859-1编码,显示不了中文。
解决:在JSP页面上方加个<%@ page contentType="text/html;charset=utf-8"%>解决。当然,也可以用charaset="gbk","gb2312"之类的编码,不过建议还是用utf-8,详细原因去看看jdon板桥里人的那篇《中文乱码终极解决方法》。
2.提交表单,在后台读取表单内容发现乱码
原因:request的默认编码问题,具体不甚清楚,没看过tomcat源代码。。。
解决:写个fileter,具体如下:
package operator;
import java.io.IOException;
import 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 {
protected String encoding = null;
protected FilterConfig filterConfig = null;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
public void destroy() {
this.encoding = null;
this.filterConfig = null;
}
protected String selectEncoding(ServletRequest request) {
return (this.encoding);
}
}
web.xml配置:
在servlet-mapping后加入以下内容:
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>operator.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.下载时,“另保存为”默认名字显示乱码
原因:不清楚。。。
在tomcat安装目录的config/sever.xml内的
<Connector
port="80" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8" />
加进最后的“URIEncoding="UTF8"
4.在后台用system.out.println()输出正常,保存到mysql数据库EMS显示乱码,读回数据也是乱码
原因:mysql默认采用的是latin1编码;
解决:创建表的时候要修改成utf-8。如果已存在表,用EMS的话,直接修改table-property里面的default charater set就可以了,其他管理工具不知道,没用过。
5.在后台用system.out.println()输出正常,保存到mysql数据库EMS显示乱码,读回数据时——居然正常了,直接往数据库里插入正常的中文,读出——居然乱码了;
原因:EMS管理工具的默认显示问题
解决:register数据库时,client default charater set改utf-8
注:这该死的问题困扰了我好长一段时间,一直以为我程序有问题,检查了N久,发现居然是工具显示问题。。
如果是在EMS SQL Manager 2007 for MySql中,它编码选项中竟然有的地方没有我们想要的编码,后来我试了一下这种方式解决了
在database registration info中,Client charset:utf8;Font charset:GB2312_CHARSET
6.COMMON-UPLOAD 上传中文名文件时,显示乱码
原因:common-upload组件默认采用系统的编码,而页面传过来的请求采用UTF-8编码。
我的系统是简体中文WINDOWS 2K3,系统编码是GBK,当页面请求过来时,UPLOAD就把UTF8编码的流直接按GBK编码了。。。如果用new String(oldStr.getBytes("gbk"),"utf8)可以发现,部分中文可以还原回去。
解决:网上的说法五花八门,甚至有归罪于这是UPLOAD的BUG,其实只要在
DiskFileUpload fu = new DiskFileUpload();
后加一句:
fu.setHeaderEncoding("utf8");
就解决了。。。有时候还是直接读英文帮助手册来得正确。。。
二、eclipse里面出乱码
Unable to find a javac compiler; com.sun.tools.javac.Main is not on the classpath. Perhaps JAVA_HOME does not point to the JDK
服务器上某些页面居然报这样的错,却又不是全部,奇怪!
在网上搜索到了些解决办法:
1、在TOMCAT5.0 中的Java Options里加入了一句:-Djava.home=d:\j2sdk1.4.2_04,再次启动TOMCAT(比如:开始-程序-tomcat-config tomcat)照着做了,结果还是无效。
2、把JAVA_HOME/lib/tools.jar拷到TOMCAT_HOME\common\lib下,重启动Tomcat
这个可以解决。
我在使用中出现的错误与此相同。我用eclipse打开,运行tomcat就会出现此错误。但是如果我用的是tomcat服务的话就没有此问题。后来在“运行-cmd”命令行窗口中查看java -verbose发现他所指向的路径是C:\Program Files\Java\j2re1.4.2_05\bin而并非我们安装时指定的jdk目录,比如我的是:D:\Java\j2re1.4.2_05\bin,所以在启动tomcat 后,访问jsp就有可能出现上述错误。而且我的中文显示的还是乱码!
同事介绍的办法:在配置环境变量时将%JAVA_HOME%\bin;放到PATH的最前面就行了。
总结:如果安装jdk的目录就是C:\Program Files\Java\就不会出现此问题。
另附:
1、设置tomcat的CATALINA_HOME 环境变量有什么作用?
CATALINA_HOME 其实就是指定tomcat的安装目录,CATALINA是Tomcat的别名,设置它是为了启动tomcat ,%CATALINA_HOME%\bin\startup.bat和catalina.bat,如果你有多个版本的tomcat,你需要启动其中的一个,这个就有用了。用记事本看\Tomcat5.0\bin目录下的startup.bat文件就明白了。从tomcat4 版本开始推荐用CATALINA_HOME ,我一直用tomcat_home定义安装目录,
2、Windows下JAVA环境变量的设置祥解
Windows下JAVA用到的环境变量主要有3个,JAVA_HOME、CLASSPATH、PATH。下面逐个分析。
JAVA_HOME指向的是JDK的安装路径,如x:\JDK_1.4.2,在这路径下你应该能够找到bin、lib等目录。值得一提的是,JDK的安装路径可以选择任意磁盘目录,不过建议你放的目录层次浅一点,如果你放的目录很深,比如x:\XXXXXX\xxxxx\XXXX\xxxx\XXXX\xxxx\XXXX\xxx……
那么,下面的步骤和以后的应用你都要受累了,呵呵。设置方法:
JAVA_HOME=x:\JDK_1.4.2
PATH环境变量原来Windows里面就有,你只需修改一下,使他指向JDK的bin目录,这样你在控制台下面编译、执行程序时就不需要再键入一大串路径了。设置方法是保留原来的PATH的内容,并在其中加上%JAVA_HOME%\bin (注,如果你对DOS批处理不了解,你可能不明白%%引起来的内容是什么意思;其实这里是引用上一步设定好的环境变量JAVA_HOME,你写成x:\JDK_1.4.2也是可以的;你可以打开一个控制台窗口,输入echo %JAVA_HOME%来看一下你的设置结果) :
PATH=%JAVA_HOME%\bin;%PATH%
同样,%PATH%是引用以前你设置的PATH环境变量,你照抄以前的值就行了。
CLASSPATH环境变量我放在最后面,是因为以后你出现的莫名其妙的怪问题80%以上都可能是由于CLASSPATH设置不对引起的,所以要加倍小心才行。
CLASSPATH=.;%JAVA_HOME%\lib\tools.jar
首先要注意的是最前面的".;",如果你看不清,我给你念念——句点分号。这个是告诉JDK,搜索CLASS时先查找当前目录的CLASS文件——为什么这样搞,这是由于LINUX的安全机制引起的,LINUX用户很明白,WINDOWS用户就很难理解(因为WINDOWS默认的搜索顺序是先搜索当前目录的,再搜索系统目录的,再搜索PATH环境变量设定的) ,所以如果喜欢盘根究底的朋友不妨研究一下LINUX。
为什么CLASSPATH后面指定了tools.jar这个具体文件?不指定行不行?显然不行,行的话我还能这么罗索嘛! 这个是由java语言的import机制和jar机制决定的,你可以查资料解决。
3、由于偶将TOMCAT作为service方式安装,所以CATALINA_HOME环境变量也没设过,如果读者不是按照这种方式请设置一个系统环境变量,设置方法同J2SDK。
变量名:CATALINA_HOME
变量值:d:\Tomcat
5.0
另外可再增加一个环境变量
变量名:CLASSPATH
变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tool.jar;%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\common\lib\servlet-api.jar;%CATALINA_HOME%\common\lib\jsp-api.jar
也是因为service安装的原因,笔者在执行一些程序的时候会出现如下错误信息:
Unable
to find a javac compiler; com.sun.tools.javac.Main is not on the classpath.
Perhaps JAVA_HOME does not point to the
JDK
错误信息是没有设置过JAVA_HOME环境变量,读者也可能碰到过这个问题,明明设置过这个环境变量,在服务里启动就会出错,但是在命令行下输入D:\Tomcat
5.0\bin\startup.bat启动却能运行,笔者找了一下原因,原来在服务里启动没有读取JAVA_HOME这个环境变量,而是在配置里定义这个环境变量的,于是偶在Java
Options里加入了一句:-djava.home=d:\j2sdk1.4.2_04,再次启动TOMCAT就OK了,
三、struts 2中乱码
在使用struts2的 struts-tags的<s:text name="login.user"/>是碰到了乱码问题。
心里愤愤,觉得这个乱码问题都解决过几次了,怎么还会被撞上了?!
先把以往需要设置的点罗列一下:
1. JSP 文件头
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page pageEncoding="UTF-8" %>
2. struts.properties中的编码设定
struts.locale = UTF-8
3. Resource的native2ascii 转码
通常这些搞定就能解决编码问题了。
再过一点在web.xml里面配置一个编码的filter:
<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ActionContextCleanUp
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
不过这次我碰到了一个这些都不能解决的问题。仍然是乱码。
仔细回想了一下自己的各个环节有什么不同,
我在eclipse里输入中文的,所以把中文素材文件设置成了utf-8格式。
这个在editplus中看起来是乱码的,刚好乱码的结果和web显示的一样。
于是问题找到了,使用editplus重新改写了一下中文。
然后native2ascii一下放上去果然就好了。