mysql乱码问题

JAVA EE编程用mysql连接数据库时,在浏览器上查看中文都变成了问号,我用的是mysql 5.0。

由于jdk中只规定了必须有一些unicode utf8
等编码的实现,
好像对汉字编码没有什么实现的硬性规定,
所以有时候就会出现乱码问题。

一、数据库访问时的乱码问题,可以数据库连接中加上useunicode =true 以及用gbk 或gb2312编码就可以了:
在建立数据库时,将数据库中的所有表的编码方式都设置为gbk,原因是JSP中也使用了gbk编码,这样统一的结果是可以减少很多不必要的编码转换问题。另外,在使用JDBC连接MySQL数据库时,连接字符串写成如下形式可以避免一些中文问题:

jdbc://mysql://hostname:port/DBname?user=username&
password=pwd&
useUnicode=True&
characterEncoding=gbk

如果是以数据源的方式连接数据库,在配置文件中使用:
<parameter>
<name>url</name>
<value>
jdbc://mysql://hostname:port/DBname?&useUnicode=True&characterEncoding=gbk
</value>
</parameter>
但是,如果使用一个已经存在的数据库,数据库的编码方式是ISO-8859-1,而Web应用中使用UTF-8,且数据库中已经有很多重要信息,因此不能 通过更改数据库的编码方式来解决问题。这个时候,在往数据库中写数据库时,一定要在JDBC连接字符串中加入“useUnicode=True& characterEncoding=ISO-8859-1”,这样可以顺利的往数据库中写入正常的数据。但是,在将数据读出数据库时,乱码又会出现,这 个时候就应该在数据取出时对其转码,可以将转码功能写为一个函数,具体实现如下:
public String charConvert(String src){
String result=null;
if(src!=null){
try{

// 使用给定的 charset 将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组->通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
result=new String(src.getBytes("ISO-8859-1"),"gbk");
}catch(Exception e)
{
result=null;
}
}
return result;
} 于是,在从数据库读出数据过后调用charConvert(rs.getString("colName")),这样就可以正常显示数据库中的中文数据了。

二、JSP中输出中文的乱码问题

所谓在JSP输出中文,即直接在JSP中输出中文,或者给变量赋中文值再输出等,这种情况下的乱码问题往往是因为没有给JSP页面制定显示字符的编码方式,解决问题如下:

·在JSP页面头部加上语句<%@ page contentType="text/html;charset=gbk"%>(在Servlet页面中使用

httpServletResponse.setContentType("text/html;charset=gbk")),最好同时在 JSP页面的head部分加上<meta http-equiv="Content-Type" content="text/html;charset=gbk">

·在每次要输出中文的地方主动转换编码方式,比如要在页面中输入“中文”二字,就可以用以下方式:

<%
String str="中文";
byte[] tmpbyte=str.getBtyes("ISO-8859-1");
str=new String(tmpbyte);
out.print(str);
%>

三、获取表单提交的数据时的中文乱码问题

在没有加任何其他处理之前,用request.getParameter(panamName)获取表单提交中的数据,且表单数据中含有中文时,返回的字 符串会出现乱码。出现这种问题的原因是Tomcat的J2EE实现对表单提交,即以POST方式提交的参数采用默认的ISO-8859-1来处理。
比如,建立一个test.jsp,内容为:
<%@ page contentTyp="text/html;charset=gbk"%>
<%
String str=request.getParameter("chStr");
if(str==null) str="没有输入值";
%>
<html>
<head>
<title>中文Test</title>
<meta http-equiv="Content-Type" content="text/html;charset=gbk">
<meta http-equiv=param content=no-cache>
</head>
<body>你输入的内容为:<%=str%><br>
<form action="test.jsp" method="post">
请输入中文:<input type="text" name="chStr">
<input type="submit" value="确定">
</form>
</body>
</html>

运行过后,在输入框中输入汉字“中文”,提交过后再显示出来后就变成了一堆乱码。解决此问题的办法有两个。一是不修改其他设置,只是在将表单中的中文数据 取出来过后再转换编码,方法如语句String str=request.getParameter("chStr");String str=new String(sre.getByte("ISO-8859-1"),"gbk"),但这种方法只是从一个局部来考虑问题,如果这样的地方太多,就不得不 将这条语句重复写很多次,在比较大的项目中,这是一种不太可行的方案。另一个方法就是让对所有页面的请求都通过一个Filter,将处理字符集设置为 gbk。具体的做法如下(在Tomcat的webapps/servlet-examples目录有一个完整的例子,也可以参考其中web.xml和 SetCharacter EncodingFilter的配置):

首先将%TOMCAT%/webapps/servlets-examples/Web-INF/classes/filters/目录下的文件 SetCharacterEncodingFilter.class拷贝到自己应用的/Web-INF/classes/com/util/filter 目录下;然后再在web.xml文件的<web-app>后面加上如下配置代码:
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>com.ccut.struts.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>gbk</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*<url-pattern>
</filter-mapping>

四、URL中的中文问题

对于直接通过在URL中传递中文参数,如“http://localhost/a.jsp?str=中文”这样的get请求,在服务端用 request.getParameter("name")时返回的往往是乱码。按以上的做法设置Filter没有用,用 request.setCharacterEncoding("gbk")的方式,仍然不管用。
例如,建立test2.jsp文件,内容为:

<%@ page contentTyp="text/html;charset=gbk"%>
<%
String str=request.getParameter("chStr");
if(str==null) str="没有输入值";
%>
<html>
<head>
<title>中文Test</title>
<meta http-equiv="Content-Type" content="text/html;charset=gbk">
<meta http-equiv=param content=no-cache>
</head>
<body>你输入的内容为:<%=str%><br>
<form action="test.jsp" method="post">
<a href="test2.jsp?chStr=中文">点击这里提交中文参数</a>
</form>
</body>
</html>

运行后,可见通过URL传递的中文参数取出来过后变成了乱码,造成这种结果的原因是Tomcat中以get方式提交的请求对query-string处理时采用了和post方法不一样的处理方式。
解决这个问题的方法是打开Tomcat安装目录下的/conf/server.xml文件,找到Connector块,往其中添加URIEncoding="gbk",添加过后完整的Connector块代码如下:
<Connector port="8080"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
debug="0" connectionTimeout="20000"
disableUploadTimeout="true"
URIEncoding="gbk"
/>

五、在Struts中证实可以解决URI传递乱码问题.

可以这样做
1.设定Tomcat的URI编码为"UTF-8":修改%tomcat%\conf\server.xml中的<Connector>在中间加入URIEncoding="UTF-8";
2.先在页面上encodeURI(url);
3.后台代码中直接取出来的中文参数就已经OK了.

不过这种方法用在servlet中行不通,在servlet中就必须对URI进行处理,Tomcat中有没有加入URIEncoding都没有差别.
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-06-15
修改mysql的my.ini文件,default-character-set=gbk,重启mysql服务即可本回答被提问者采纳
第2个回答  2010-06-15
<head>

<meta http-equiv="Content-Type" content="text/html;charset=gbk">

</head>

charset=gbk中的gbk换成 utf-8 或 gb2312 看看~不然就重新安装下mysql,选择utf-8 或 gb2312
第3个回答  2020-11-24

一、转码失败
在数据写入到表的过程中转码失败,数据库端也没有进行恰当的处理,导致存放在表里的数据乱码。
针对这种情况,前几篇文章介绍过客户端发送请求到服务端。
其中任意一个编码不一致,都会导致表里的数据存入不正确的编码而产生乱码。
比如下面简单一条语句:
set @a = "文本字符串";
insert into t1 values(@a);

    变量 @a 的字符编码是由参数 CHARACTER_SET_CLIENT 决定的,假设此时编码为 A,也就是变量 @a 的编码。

    2. 写入语句在发送到 MySQL 服务端之前的编码由 CHARACTER_SET_CONNECTION 决定,假设此时编码为 B。

    3. 经过 MySQL 一系列词法,语法解析等处理后,写入到表 t1,表 t1 的编码为 C。
    那这里编码 A、编码 B、编码 C 如果不兼容,写入的数据就直接乱码。


    二、客户端乱码
    表数据正常,但是客户端展示后出现乱码。
    这一类场景,指的是从 MySQL 表里拿数据出来返回到客户端,MySQL 里的数据本身没有问题。客户端发送请求到 MySQL,表的编码为 D,从 MySQL 拿到记录结果传输到客户端,此时记录编码为 E(CHARACTER_SET_RESULTS)。
    那以上编码 E 和 D 如果不兼容,检索出来的数据就看起来乱码了。但是由于数据本身没有被破坏,所以换个兼容的编码就可以获取正确的结果。
    这一类又分为以下三个不同的小类:

    1)字段编码和表一致,客户端是不同的编码
    比如下面例子, 表数据的编码是 utf8mb4,而 SESSION 1 发起的连接编码为 gbk。那由于编码不兼容,检索出来的数据肯定为乱码。

    2)表编码和客户端的编码一致,但是记录之间编码存在不一致的情形
    比如表编码是 utf8mb4,应用端编码也是 utf8mb4,但是表里的数据可能一半编码是 utf8mb4,另外一半是 gbk。那么此时表的数据也是正常的,不过此时采用哪种编码都读不到所有完整的数据。这样数据产生的原因很多,比如其中一种可能性就是表编码多次变更而且每次变更不彻底导致(变更不彻底,我之前的篇章里有介绍)。举个例子,表 t3 的编码之前是 utf8mb4,现在是 gbk,而且两次编码期间都被写入了正常的数据。

    3)每个字段的编码不一致,导致乱码和第二点一样的场景。不同的是:非记录间的编码不统一,而是每个字段编码不统一。举个例子,表 c1 字段 a1,a2。a1 编码 gbk,a2 编码是 utf8mb4。那每个字段单独读出来数据是完整的,但是所有字段一起读出来,数据总会有一部分乱码。


    三、LATIN1
    还有一种情形就是以 LATIN1 的编码存储数据
    估计大家都知道字符集 LATIN1,LATIN1 对所有字符都是单字节流处理,遇到不能处理的字节流,保持原样,那么在以上两种存入和检索的过程中都能保证数据一致,所以 MySQL 长期以来默认的编码都是 LATIN1。这种情形,看起来也没啥不对的点,数据也没乱码,那为什么还有选用其他的编码呢?原因就是对字符存储的字节数不一样,比如 emoji 字符 "❤",如果用 utf8mb4 存储,占用 3 个字节,那 varchar(12) 就能存放 12 个字符,但是换成 LATIN1,只能存 4 个字符。

相似回答