中文乱码问题的确令人头疼,接收get/post表单参数,或者从数据库取中文数据,都有可能出现乱码。
因为各个环境下使用的字符编码不同,HTML2.0 - HTML4.01、jsp默认使用ISO-8859-1,mysql数据库默认使用latin,HTML5使用UTF-8,ISO 8859和latin两种字符编码都不支持中文,具体可以参见下表
字符编码 | 说明 |
ISO/IEC 8859 | 欧洲字符集,支持丹麦语、荷兰语、德语、意大利语、拉丁语、挪威语、葡萄牙语、西班牙语,瑞典语等,1987 年首次发布。 ASCII 编码只包含了基本的拉丁字母,没有包含欧洲很多国家所用到的一些扩展的拉丁字母,比如一些重音字母,带音标的字母等,ISO/IEC 8859 主要是在 ASCII 的基础上增加了这些衍生的拉丁字母。 |
Shift_Jis | 日语字符集,包含了全角及半角拉丁字母、平假名、片假名、符号及日语汉字,1978 年首次发布。 |
Big5 | 繁体中文字符集,1984 年发布,通行于台湾、香港等地区,收录了 13053 个中文字、408个普通字符以及 33 个控制字符。 |
GB2312 | 简体中文字符集,1980 年发布,共收录了 6763 个汉字,其中一级汉字 3755 个,二级汉字 3008 个;同时收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的 682 个字符。 |
GBK | 中文字符集,是在 GB2312 的基础上进行的扩展,1995 年发布。 GB2312 收录的汉字虽然覆盖了中国大陆 99.75% 的使用频率,满足了基本的输入输出要求,但是对于人名、古汉语等方面出现的罕用字(例如朱镕基的“镕”就没有被 GB2312 收录),GB2312 并不能处理,所以后来又对 GBK 进行了一次扩展,形成了一种新的字符集,就是 GBK。 GBK 共收录了 21886 个汉字和图形符号,包括 GB2312 中的全部汉字、非汉字符号,以及 BIG5 中的全部繁体字,还有一些生僻字。 |
GB18030 | 中文字符集,是对 GBK 和 GB2312 的又一次扩展,2000 年发布。 GB18030 共收录 70244 个汉字,支持中国国内少数民族的文字,以及日语韩语中的汉字。 |
UTF-8 | Unicode字符集 称为统一码、万国码,世界通用。 UTF 是 Unicode Transformation Format 的缩写,意思是“Unicode转换格式”,后面的数字表明至少使用多少个比特位(Bit)来存储字符。 UTF-8是一种变长的编码方案,使用 1~6 个字节来存储; |
UTF-16 | UTF-16介于 UTF-8 和 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变。 |
UTF-32 | UTF-32是一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储; |
目前,最常用的中文编码类型是GBK和UTF-8,GBK是Windows默认的中文编码方案,而UTF-8将中文推向全世界。
针对中文乱码,解决方法就是:统一所有的字符编码为GBK/UTF-8
1.MYSQL数据库的存取乱码问题:
登录mysql设置字符集
让数据库支持中文编码的数据。其中UTF-8也可以改成gbk。
show variables like 'char%'; set character_set_database='utf-8'; set character_set_server='utf-8'; status;
2.HTML网页乱码问题:
如果使用的是html5,则不用修改,默认即为utf-8
你问我怎么知道自己用的是html5?哈哈,第1行改成简单的就行了
如果不是h5或者想用gbk,在html文件中添加修改第5行的charset为utf-8或gbk
Content-Type的charset表示服务器发送给客户端时的内容编码
1 DOCTYPE HTML> 2 <html> 3 <head> 4 <title>修改乱码title> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6 head> 7 8 <body> 9 <p>你好!p> 10 body> 11 html>
3.JSP网页乱码问题
jsp的本质是一个servlet,由tomcat这种servlet容器解析,所以比普通的html多了一步
添加修改第一行的pageEncoding为UTF-8/GBK,表示修改jsp的输出方式
这里注意 UTF-8一定要大写 ,小写会出现一些莫名其妙的错误,原因至今是个谜…
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 3 DOCTYPE HTML> 4 <html> 5 <head> 6 <title>C学习系统title> 7 <meta http-equiv="pragma" content="no-cache"> 8 <meta http-equiv="cache-control" content="no-cache"> 9 <meta http-equiv="expires" content="0"> 10 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 11 <meta http-equiv="description" content="This is my page"> 12 head> 13 14 <body> 15 This is my JSP page. <br> 16 body> 17 html>
4.servlet请求/响应的乱码问题:
在用到servlet的地方添加以下代码
request.setCharacterEncoding("UTF-8");//设置请求编码 response.setCharacterEncoding("UTF-8");//设置响应编码
5.一劳永逸的方法——过滤器:
新建一个Java类,继承Filter,Filter位于javax.servlet包下
1 package filter; 2 3 import java.io.IOException; 4 5 6 import javax.servlet.Filter; 7 import javax.servlet.FilterChain; 8 import javax.servlet.FilterConfig; 9 import javax.servlet.ServletException; 10 import javax.servlet.ServletRequest; 11 import javax.servlet.ServletResponse; 12 import javax.servlet.annotation.WebFilter; 13 14 @WebFilter("/*") 15 public class EncodingFilter implements Filter { 16 17 public void init(FilterConfig fConfig) throws ServletException { 18 } 19 20 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 21 throws IOException, ServletException { 22 23 //response.setContentType("text/html;charset=UTF-8"); 24 request.setCharacterEncoding("UTF-8"); 25 response.setCharacterEncoding("UTF-8"); 26 27 chain.doFilter(request, response); 28 } 29 30 public void destroy() { 31 } 32 33 }
第14行使用了Servlet3.0的注解,配置过滤器的应用范围,/* 代表所有文件
如果你用浏览器作为客户端的话,加上第23行,和标题2效果相同
用不了或不想用注解,可以使用原始xml配置方法:
在你的项目web根目录下创建web.xml文件,添加修改第15-22行
1 xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns="http://xmlns.jcp.org/xml/ns/javaee" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 5 id="WebApp_ID" version="3.1"> 6 <display-name>project_namedisplay-name> 7 <welcome-file-list> 8 <welcome-file>index.htmlwelcome-file> 9 <welcome-file>index.htmwelcome-file> 10 <welcome-file>index.jspwelcome-file> 11 <welcome-file>default.htmlwelcome-file> 12 <welcome-file>default.htmwelcome-file> 13 <welcome-file>default.jspwelcome-file> 14 welcome-file-list> 15 <filter> 16 <filter-name>EncodingFilterfilter-name> 17 <filter-class>filter.EncodingFilterfilter-class> 18 filter> 19 <filter-mapping> 20 <filter-name>EncodingFilterfilter-name> 21 <url-pattern>/*url-pattern> 22 filter-mapping> 23 web-app>
16和20行对应,表示你起的过滤器名字,17行表示对应的java类完整路径(酌情修改),21行表示应用范围
如果你的tomcat版本在7.0以下,在接收get请求的时候,要使用以下方法转码才能得到正确的中文内容
String value = new String(request.getParameter(param_name).getBytes("ISO-8859-1"),"UTF-8");
request.getParameter(String param_name):接收参数param_name的内容
getBytes(String decode):表示根据指定的decode编码返回某字符串在该编码下的byte数组表示
String(bytes[] bt,String encode):重新以encode格式编码,返回字符串
6.getParameter和getAttribute的区别:
getParameter(String param)专门用来接收表单等请求数据,返回的一定是字符串类型
getAttribute(String param)表示获取参数,返回的是Object类型,强制转换后可以恢复成各种实体类,往往和setAttribute(String param,Object obj)搭配使用
比如说:
session.setAttribute("userInfo",user);
User user=(User)session.getAttribute("userInfo");
User是一个bean实体类,第一行把它的实例化对象存入了session会话中,起名叫userInfo
第二行从session中获取到了userInfo,并强转恢复为User类型
session的作用范围是一次会话,通俗说就是你打开浏览器浏览那个网站,会话就开始;关闭或注销登录,一次会话就结束,session的内容会销毁