1.各种字符集的意义
Unicode字符集:它是世界上所有字符的统一编码,Unicode字符集包含了世界上所有文字的二进制编码。但是它没有规定字符的存储方式。
UTF-8:它是Unicode字符集的一种实现方式,即Unicode的一种存储方式。
GBK/GB2312:都是中文的的一种字符编码,只不过GBK的表示范围更广。
ISO-8859-1:是ASCII的扩展字符集,包括了基本的英文字符和一些欧洲字符。
所以,如果我们的网页包含汉字的话,只能用UTF-8/GBK/GB2312这三种中的一种。一般来说,UTF-8编码能够更好地实现国际化,因为它是Unicode(Unique Code)的实现方式,可以表示所有字符。
2.如何在各种字符编码间转换
说起字符乱码,还是得怪我们的语言种类太多,每种语言都有自己的字符。一种字符用一种编码方式,中文用GBK/GB2312,英文用ASCII和ISO-8859-1。为了交流的方便,便有了Unicode字符,而Unicode字符又没规定如何存储,于是UTF-8编码方式就出现了。在Java中,如果要在几种字符方式之间转换,可以用getBytes(String charset)方法和new String(byte[] byte, String charset)方法。其中
①String.getBytes(String charset)是将String字符串根据charset编码方式编码。
getBytes方法其实是将某一个字符串中的字符转换成对应字符集中的字节数组。
String str2 = "abcde";
byte[] strByte2 = str2.getBytes("iso-8859-1");
for(byte b : strByte2)
{
System.out.print(b + " "); //输出:97 98 99 100 101
}
上图这个例子,将字符串『abcde』转成字节数组就分别是:97 98 99 100 101。
这是一个将字符串专场字节的过程,是一个编码的过程。
②new String(byte[] byte, String charset)是将byte字节数组转换成charset编码方式下的字符串。
比如:
String str = "这是陈树义的博客";
byte[] strByte = str.getBytes("utf-8"); //将字符串用utf-8方式编码
System.out.println(strByte.length); //一共有8个汉字,一个汉字用3个字节表示,一共有24个字节。
String newString = new String(strByte, "utf-8"); //将字节数组用utf-8编码方式还原成数组
System.out.println(newString); //输出:"这是陈树义的博客"
③有时候传输数据的时候要求数据必须以ISO-8859-1编码方式传输,这时你可以先将数据以ISO-8859-1方式保存。到达指定页面之后再将数据再转换一次,从而得到指定的字符。在下面这个例子,原本的页面是UTF-8编码的,但是传输的时候要求用ISO-8859-1编码,于是我们先转换成ISO-8859-1表示的字符串,即:
String str = "传输必须用ISO-8859-1编码";
str = new String(str.getBytes("gb2312"), "iso-8859-1");
此时,str字符串就是用iso-8859-1编码方式表示的数据,但是直接输出它将是乱码(因为iso-8859-1没有中文字符)
到了指定页面之后就再转过来,即:
String newStr = new String(str.getBytes("iso-8859-1"), "utf-8");
完整的例子:
String str = "传输必须用ISO-8859-1编码";
str = new String(str.getBytes("gb2312"), "iso-8859-1");
System.out.println(str); //输出乱码
String newStr = new String(str.getBytes("iso-8859-1"), "gb2312");
System.out.println(newStr); //输出『传输必须用ISO-8859-1编码』
3.JSP页面中涉及到的编码
JSP页面中设计到的有三个编码,分别是pageEncoding、contentType和meta。
<%@ page language="java" pageEncoding="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的中文处理");%>
</body>
</html>
在上面的代码中的①、②、③分别就是JSP中的三个编码。
①<%@page pageEncoding="gb2312"%>
pageEncoding表示JSP文件转换成Java类文件时使用的编码。因为JSP文件是通过Tomcat进行解析转换成java文件,在转换成Java文件时就会根据用户设置的编码方式进行编码。即如果你在JSP页面上有中文字符,但是你在pageEncoding声明为ISO-8859-1。那么JSP文件在转成Java文件时就会用ISO-8859-1去编码,而ISO-8859-1中不包含中文字符,所以当我们打开Tomcat目录下对应的缓存文件(在Tomcat的work目录下)时会看到对应的Java文件中的中文字符是乱码。也就是说,这时候在Java文件中就是乱码了,那么这时你即使JSP页面设置正确了,但你在前台得到的数据还是乱码。因此,pageEncoding属性也要设置正确,一般设置成“UTF-8"可以更好地支持国际化。
②<%@ page contentType="text/html;charset=gb2312" %>
contentType指定了服务器发送给客户端时的内容编码。当用户请求数据时,Tomcat会请求并解析响应的class文件,在解析之时就会根据用户设置的contentType来解码,并将解码后的数据发送到客户端显示。这里和pageEncoding是对应的,如果你在pageEncoding中设置是GB2312,而在contentType中设置UTF-8,那么有可能出现出现乱码。因为Class文件是用GB2312编码的,而你解码用UTF-8,可能会导致解码不正确。所以,pageEncoding和contentType最好使用统一编码方式。
③<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
meta标签可以控制浏览器用某种特定的字符集解释页面。
疑问:
①其实现在还不是很清楚JSP文件转换成Java文件,编译成class文件,以及用户请求这些过程涉及的编码问题,对pageEncoding、contentType、meta的理解也停留在一个很浅的水平。有机会请再弄清楚!
4.页面中文乱码
前面已经说过,如果pageEncoding设置错误,那么在Java类文件中就已经是乱码,这时候无论如何都是错误的。但是如果pageEncoding设置正确,那么还出现乱码,那么出现错误的应该就是contentType这个属性了。这个属性指的是JSP页面中使用的字符集(其实与meta好像差不多)。我做过一些测试,如果你将contentType设置成iso-8859-1,那么网页中的中文不能显示。如果设成UTF-8/GBK/GB2312,那么中文可以显示。
5.表单提交数据乱码
表单提交方式有两种方式,一种是GET方式,一种是POST方式。这里只讨论GET方式(请在另文补充POST方式)。
我们在一个页面提交中文数据,到另外一个页面用request.getParameter得到数据。这时候如果直接用request.getParameter得到数据,然后直接输出将会乱码。因为Tomcat在传输数据的时候进行了编码的转换(这涉及到Tomcat的源码内容,请继续补充)。如果要得到正确的数据,请进行编码转换,即做以下操作:
String name = new String(request.getParameter("name").getBytes("iso-8859-1"), "gb2312");
这里的表单提交出现乱码似乎与contentType没有必然的关联,因为contentType是控制页面的显示的字符集,而提交表单出现乱码主要是在提交数据后与得到数据前的数据传输过程。
6.数据库乱码(不清楚)
数据库乱码有两种可能,一种是你request得到的数据就是乱码的,另一种就是你request得到的数据正确,而存入数据库时乱码。第一种情况,参考第5点的解决方式。第二种情况,则是数据库的问题,暂时不清楚。
总结:到现在而知,对于JSP编码的方式还不是很清楚,虽然能解决问题了,但是弄不清许多问题。这些问题有:
①JSP->JAVA->class文件,这个过程涉及到的编码是怎样的。还有当用户请求,服务器发给客户端时,与contentType的关系是这样的?
②Request请求数据后,浏览器是怎么发送数据的,这中间的编码是怎样的?
参考资料:
*解决中文JSP乱码问题
*JSP中的pageEncoding和contentType属性
*String.getBytes()方法
分享到:
相关推荐
### JSP安全编程实例浅析 #### 一、引言 在现代Web开发中,JavaServer Pages (JSP)作为一种动态网页技术被广泛应用于构建复杂的企业级应用。然而,随着互联网的发展,各种针对Web应用程序的安全威胁也日益增多。...
【标题】:“论坛系统 hibernate jsp hibernate 毕业论文项目” 【描述】:这个项目是一个基于Java技术栈的论坛系统实现,主要利用了Hibernate ORM框架与JSP(JavaServer Pages)进行开发,是适合学生作为毕业论文...
**浅析AJAX乱码及错误解决方案** 在当前的网络环境中,JavaScript被广泛应用于网页交互,而AJAX技术更是让动态加载数据变得无处不在。然而,由于编码规范的不一致,尤其是在各种浏览器环境中,经常会出现乱码和...
而write方法则适用于需要精确控制字符输出流的场景,比如在需要指定字符编码的情况下。 在开发JSP页面时,了解out.print()和out.write()的区别非常关键。正确的使用这两种方法,不仅可以避免出现...
本文着重对视频点播系统进行分析和研究,浅析视频点播的现状和存在的一些问题并对此进行研究,通过对问题和现状的分析研究和对用户需求的一个简单整理建模,设计并且实现一个视频点播系统。 视频点播系统采用的开发...
本文着重对济南旅游网站进行分析和研究,浅析济南旅游网站的现状和存在的一些问题并对此进行研究,通过对问题和现状的分析研究和对用户需求的一个简单整理建模,设计并且实现一个济南旅游网站。 济南旅游网站采用的...
本文着重对小学生课外知识学习网站进行分析和研究,浅析小学生课外知识学习网站的现状和存在的一些问题并对此进行研究,通过对问题和现状的分析研究和对用户需求的一个简单整理建模,设计并且实现一个小学生课外知识...
Servlet过滤器,URL编码,安全Web服务都是用于Java,以实现应用程序安全性。而PHP没有这种安全处理的概念。 5、反射概念:Java从第一天开始就在内部具有反射概念,如接口,重复类,抽象类或方法概念。PHP 5.0以前...
- 张超, 基于JSP的数据库连接技术浅析[J]. 福建电脑, 2014, 28(12):80-81. - 陈倩, 刘胜, 焦壵. 基于JSP的培训管理信息系统研究[J]. 机械, 2013,40(009):10-15. - 李刚, 疯狂android讲义[M]. 北京: 电子工业出版...
Struts2提供了丰富的标签库,如`<s:textfield>`, `<s:submit>`, `<s:iterator>`等,这些标签用于简化JSP页面的编码,同时增强页面的动态性和可维护性。 #### 7. 表达式OGNL OGNL(Object-Graph Navigation ...
- **JSON-RPC概述**:JSON-RPC是一种使用JSON来编码远程过程调用的方法。 - **JSON示例**:通过实例展示如何在Struts2中使用JSON。 - **Struts2与JSON示例**:详细介绍如何在Struts2中集成JSON处理。 #### 十二、...
- **投票管理系统**、**无纸化办公管理系统**、**数据采集系统**等章节介绍了实际项目的开发过程和技术要点,包括需求分析、设计、编码和测试等方面。 通过上述知识点的梳理,可以清晰地了解到Struts2.0的学习路径...