先打个比方,总司令发出一条命令是“每个士兵都把枪检查好”,这条命令需要 ‘总司令-->师长-->团长-->营长-->班长-->各个士兵’ ,这5步才能传到,其中就需要保证每个长的语言都要与总司令的语言一致,否则这条命令就会出错。语言一致,就相当于编码方式一致。
分析中文乱码问题的总原则是,找到中文的起始点(在哪输入的中文),一步一步分析检查,要保证每一步是否设置编码为gbk(或gb2312或gb18030),如果某一步设置的编码方式不是gbk(或gb2312或gb18030),或者默认编码(默认编码可能不是直接通过代码显示声明,而是需要在工具界面的属性中设置)不是gbk(或gb2312或gb18030),那么就会出现中文乱码。也就是说,从中文发起者开始,每一步的交接都要保证编码一致。
从JSP页面开始,假设JSP页面本身有中文,就需要设置本页面的编码为gbk。
一、关于JSP页面的编码问题
JSP页面中第一条语句:<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK"%>
language="java"表示:JSP页面中内嵌在<%%>中的编程语言为java
pageEncoding="GBK"表示:在服务器端中,JSP文件本身的编码为GBK
contentType="text/html; charset=GBK"表示:
当浏览器访问服务器中的JSP文件时,JSP文件需要进行两次编译,第一次是xx.JSP-->xx.java(JSP到Servlet),第二次是xx.java-->xx.class(Servlet编译为字节码文件),然后xx.class加载到JVM中运行。 在第一次编译中,JSP文件编译为Java源文件,pageEncoding="GBK"会告诉JSP引擎,该JSP文件本身是GBK编码的。Servlet在执行的时候有一个输出流out,通过这个输出流把执行过程中需要输出的内容全部输出到一个文件中, contentType="text/html; charset=GBK" 这句话就告诉输出流out“我所输出的内容是text/html类型的,并且内容编码为GBK”,因此,Servlet执行完后会有一个对应的text/html文件生成。
然后服务器就把这个text/html文件输出了,最后把这个text/html文件传到浏览器,当到达浏览器后,浏览器就解析这个文件(注意,虽然这个文件本身就是一个text/html文件,但浏览器可不知道这个文件是text/html类型的),当浏览器解析到--<meta http-equiv="Content-Type" content="text/html; charset=GBK">--这条命令时,浏览器就知道了,这个文件是text/html类型的,并且文件内容的编码为GBK,接下来浏览器就按照text/html类型,内容编码GBK来解析这个文件了。
综上所述:从服务器中JSP文件到浏览器显示页面的步骤为:
服务器JSP------>>(<%@ page pageEncoding="GBK"%>告诉服务器JSP文件本身编码)服务器Servlet
------>>(<%@ page contentType="text/html; charset=GBK" %>告诉out输出流,输出内容的类型是html,并且内容编码是GBK)服务器HTML文件
------>>(<meta http-equiv="Content-Type" content="text/html; charset=GBK">告诉浏览器,接受到的这个文件是html类型的,并且文件内容的编码是GBK)浏览器HTML文件
------>>浏览器解析并显示接收的文件
以上为不涉及到数据库的情况下,B/S的编码设置。
二、JSP中存在数据库操作的情况下编码问题
JSP编译为Servlet后,数据库操作是在执行Servlet时进行的。
执行insert语句时,Servlet(就是一个.java文件)中的中文会插入到数据库中,首先要设置好本身java页面的编码为GBK,在eclipse中这样设置:
Window--Preference...--General--Workspace 下设置默认的encoding为GBK。这样就相当于声明了在数据库命令行中输入的中文为GBK编码的。其次保证被操 作的database和table的编码都为GBK,这样做:在新建一个database后,设置这个database的编码为GBK,即执行这条语句----
alter database 数据库名 default character set 'GBK' ;
在创建table的时候声明----charset='GBK';
经过这两步后就能保证插入到数据库表中的中文不出现乱码了。
执行select语句时,既然数据库表中没有中文乱码,那么在Servlet中执行select语句从表中拿出来的中文也就不会有乱码,从而,从out输出流一直到浏览器中
显示也就不会出现中文乱码。
最后总结:
当JSP出现中文乱码时,按一下步骤检查:
1、检查JSP文件的“三处”
<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK"%>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
2、检查database的默认字符集是否为GBK: show variables like '%char%' ;
3、检查table的默认字符集是否为GBK: show table status from 数据库名 like '%表名%' ;
4、检查表中字段(column)的默认字符集是否为GBK:show full columns from 表名;
5、在以上三步中,如果出现字符集不为GBK,则应删除(先备份),再重新创建并设置默认字符集GBK;