java的web乱码问题

lliiqiang 2015-12-08 04:58:39
乱码问题让程序员非常烦躁,因为它不涉及到任何业务逻辑,至少我一直不想考虑它,但是又不能不考虑它,因为英语才是计算机的本来语言,要想正确显示中文必须解决乱码问题,说白了就是编码问题。网上有很多解释乱码的,但是大多数都没有解释清楚这个问题。
要想搞清楚如何解决编码首先要明白,在网络上传递数据的时候传递都是byte[]字节,这里我用write方法代表输出字节流,read代表读入输入流。众所周知java内部的编码是unicode编码,而最终计算机系统内部是转为机内码,也就是说所有的编码在计算机内部处理的时候都要转为机内码,计算机才识别它.而对于java最终显示到操作系统中的时候自然会自动转为机内码
那么当你想把字符串以一种编码格式传递的时候,就需要用到String类的getBytes方法将字符串转为相应编码的字节流。例如:

write(abc.getBytes("GB2312"));

这就是说把字符串abc从unicode编码转为GB2312
那么对于接收端必须这么接收:

String str=new String(read(),"GB2312");

即将传递过来的字节流视为GB2312编码转为unicode构造为字符串str
如果变为

String str=new String(read(),"utf-8");

那么自然会出现编码错误,因为发送的是GB2312编码,你却把它当做utf-8编码,自然就乱了。
造成乱码的基本原理是这样,实际jsp开发问题如下:(前台用html代码,还有数据库,我为了方便起见,都用java代码描述它们转码过程,让大家明白整个过程)
首先是jsp或者java文件本身编码,对于jdk来说它也是用unicode编码,那么我们写java文件的时候,如果使用的是操作系统的txt文件就会保存为操作系统的编码格式(有的系统允许指定相应编码保存文件)。当然一般程序中很少有中文,而英文基本上编码一致,而jdk编译为class文件的时候会转为unicode编码,虚拟机自然以unicode编码解析它,执行它。当然对于变量 属性方法 类命名我们一般使用英文,对于字符串常量中的中文我们可以使用java的转义字符\u+(4位的中文的unicode编码)表示,当然这样很麻烦,还要编码。
不过如果使用eclipse等软件就可以设置保存的文件编码,软件编译之前会帮助我们转码为unicode,导入其它java文件的时候也可以指定它的编码格式为保存它时用的编码格式.

不过在jsp中,jsp文件是在被使用的时候被解析,需要告诉服务器当前文件的编码格式,这个 就需要jsp的page指令的pageEncoding属性告诉服务器这个文件的编码格式

<%@ page language="java" pageEncoding="utf-8" %>


接下来是发送和接收数据.
首先是html提交表单,通常提交表单的时候字符集使用的是页面的字符集例如:
<html>
<head>
<title></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>
在发送的时候,实际上是做了这样的操作:

write(abc.getBytes("GB2312"));

当然你也可以指定form表单提交时用的字符集:
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<form name="form1" method="post" action="process.jsp" accept-charset="GBK">//这里指定提交表单的字符集
<div align="center">
<input type="text" name="name">
<input type="submit" name="Submit" value="Submit">
</div>
</form>
</body>
</html>
...全文
137 4 打赏 收藏 举报
写回复
4 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
肥老 2015-12-13
谢谢楼主,我看了你的帖子问题终于解决了,GET方法的表单只要把<%=request.getParameter("first_name")%>改成<%=new String(request.getParameter("first_name").getBytes("ISO-8859-1"),"gb2312")%>就能解决中文乱码问题了。
  • 打赏
  • 举报
回复
肥老 2015-12-08
我遇到了JSP表单中文乱码问题,请帮我看看: Hello.htm

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=gb2312">
</head>
<body>
<form action="main.jsp" method="GET">
First Name: <input type="text" name="first_name">
<br />
Last Name: <input type="text" name="last_name" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
main.jsp

<%@ page contentType="text/html; charset=GB2312"%>
<%
request.setCharacterEncoding("gb2312");
%>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=gb2312">
<title>Using GET and POST Method to Read Form Data</title>
</head>
<body>
	<center>
		<h1>Using GET and POST Method to Read Form Data</h1>
		<ul>
			<li><p>
					<b>First Name:</b>
					<%=request.getParameter("first_name")%>
				</p></li>
			<li><p>
					<b>Last Name:</b>
					<%=request.getParameter("last_name")%>
				</p></li>
		</ul>
		</center>
</body>
</html>
  • 打赏
  • 举报
回复
lliiqiang 2015-12-08
还有我们经常会把数据存到数据库中,然后以后取出它,这又涉及到数据库的编码问题,对于mysql数据库使用如下url地址:jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gb2312,这里编码被设定为表单提交时设置的编码 在url中参数characterEncoding代表编码格式,useUnicode=true代表返回unicode编码,因为java自身使用的就是unicode编码 其实这样做对于java来说就相当于数据库做了下面地操作:

byte[] str=new String(read(),"gb2312").getByte();//str就直接返回给java
也就是说数据库把java传递的字节流视为gb2312保存起来,(保存的编码是数据库自己定义的)最终返回给java的是unicode编码,所以转码过程不需要再由java进行,否则转码两次有可能会出现乱码. 那么对于上面的表单提交的情况,保存数据库的页面来说只需要
<%@ page contentType="text/html; charset=gb2312"%>//再次注明这个编码要和下面html编码一致
<%
String str=request.getParameter("name");
str=new String(str.getBytes("ISO-8859-1"),"");//ISO-8859-1要与Tomcat设置的一样,gb2312要和发送页面设置的提交表单编码一致,
save(str);//str被转为原来的gb2312编码
%>
<html>
   <head>
    <title>JSP的中文处理</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
   </head>
   <body>
保存成功
   </body>
</html>
从数据库取数据的时候只需要:

<%@ page contentType="text/html; charset=gb2312"%>//再次注明这个编码要和下面html编码一致
<%
String str=readdatabase();//数据库自动帮助我们转为unicode编码,我们无需再转码,只需要返回数据的时候编码与客户端统一就可以了
%>
<html>
   <head>
    <title>JSP的中文处理</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">//这里要和page指令中指定的编码一致。
   </head>
   <body>
    <%=str%>
   </body>
</html>
编码有的时候还涉及到发送电子邮件,处理方式和上面的差不多都是采用设置编码字符集。
  • 打赏
  • 举报
回复
lliiqiang 2015-12-08
然后是Tomcat服务器接收处理它。 Tomcat服务器默认使用ISO-8859-1,那么它在默认情况下会转码为:
new String(read(),"ISO-8859-1");
当然在Tomcat的conf文件夹的server.xml文件中,可以使用URIEncoding属性设置某个端口的编码格式

<Connector port="8090" protocol="HTTP/1.1"   
             maxThreads="150" connectionTimeout="20000"   
             redirectPort="8443" URIEncoding="utf-8" />  
这里就可以看出问题了,比如上面说的html发送的是gb2312编码而Tomcat却把它当做ISO-8859-1编码,自然会乱码 所以我们需要转码:

String str=request.getParameter("name");
str=new String(str.getBytes("ISO-8859-1"),"gb2312");
因为html发送的时候按照gb2312编码,而Tomcat接收字节流的时候,按照ISO-8859-1解码。 str=new String(str.getBytes("ISO-8859-1"),"gb2312");这句话就反过来,按照ISO-8859-1编码再按照gb2312解码。就这么还原了字符串, 当然更加直接的办法就是

request.seCharacterEncoding ("gb2312");//它相当于使用代码new String(read(),"gb2312");获取客户端传递的字节流
事情到此还没有完,因为java还要返回给客户端,这个时候又要用到jsp的指令的contentType属性

<%@ page language="java" import="java.util.*" contentType="text/html;charset=gb2312"%> 
这句话是什么意思呢?这句话是说返回给客户端的时候转为gb2312编码,归咎于代码上实质上就是返回给客户端的时候会执行如下代码

write(str.getBytes("gb2312"));
而返回给客户端html的时候,要告诉客户端html的编码,因此要用html告知客户端当前页面编码:

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
此时客户端相当于执行了

String str=new String(read(),"gb2312");//这样获取服务器端返回的数据
这样编码就统一了,于是接受页面代码就变成了:

<%@ page contentType="text/html; charset=gb2312"%>//再次注明这个编码要和下面html编码一致
<%
String str=request.getParameter("name");
str=new String(str.getBytes("ISO-8859-1"),"gb2312");//ISO-8859-1要与Tomcat设置的一样,gb2312要和发送页面设置的提交表单编码一致,
%>
<html>
   <head>
    <title>JSP的中文处理</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">//这里要和page指令中指定的编码一致。
   </head>
   <body>
    <%=str%>
   </body>
</html>
  • 打赏
  • 举报
回复
相关推荐
发帖
Web 开发

8.0w+

社区成员

Java Web 开发
社区管理员
  • Web 开发社区
加入社区
帖子事件
创建了帖子
2015-12-08 04:58
社区公告
暂无公告