0 web.xml中注册的CharacterEncodingFilter

<!-- 配置字符集过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>

上面的配置相当于servlet中的 request.setCharacterEncoding("UTF-8")。

1 post请求

    通过jquery.ajax的post请求,不进行request.setCharacterEncoding("UTF-8");也可以收到中文,我发现收到请求后直接request.getCharacterEncoding得到的已经是UTF-8了。查看Request头部发现含有charset=UTF-8。可能因为请求头里指定了编码方式,所以将按照这种方式编码。

而对于form表单的post请求,request.getCharacterEncoding得到的是null,所以需要进行request.setCharacterEncoding。

所以最好都设置上request.setCharacterEncoding("UTF-8");以应付不同的请求。

2 get请求

    但是上面的设置方法是针对POST请求的,tomacat对GET和POST请求处理方式是不同的。在Tomcat5.0中,默认情况下使用ISO- 8859-1对URL提交的数据和表单中GET方式提交的数据进行重新编码(解码),而不使用request.getCharacterEncoding里的参数对URL提交的数据和表单中GET方式提交的数据进行重新编码(解码)。

要解决该问题(也可以在java后台中用getBytes转换),应该在Tomcat的配置文件server.xml的Connector标签中设置useBodyEncodingForURI或者 URIEncoding属性,其中useBodyEncodingForURI参数表示是否用request.setCharacterEncoding 参数对URL提交的数据和表单中GET方式提交的数据进行重新编码,在默认情况下,该参数为false(Tomcat4.0中该参数默认为true)。URIEncoding参数指定对所有GET方式请求(包括URL提交的数据和表单中GET方式提交的数据)进行统一的重新编码(解码)的编码。

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>

URIEncoding和useBodyEncodingForURI区别是,URIEncoding是对所有GET方式的请求的数据进行统一的重新编码(解码),而useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数对数据进行的重新编码(解码),不同的页面可以有不同的重新编码(解码)的编码。所以对于URL提交的数据和表单中GET方式提交的数据,可以修改 URIEncoding参数为浏览器编码或者修改useBodyEncodingForURI为true(这个时候request.setCharacterEncoding为null),并且在获得数据的JSP页面中 request.setCharacterEncoding参数设置成浏览器编码。

3 编码顺序

    对于发送数据,服务器按照response.setCharacterEncoding—contentType—pageEncoding的优先顺序,对要发送的数据进行编码。

1、pageEncoding="UTF-8"的作用是设置JSP编译成Servlet时使用的编码。

2、contentType="text/html;charset=UTF-8"的作用是指定对服务器响应进行重新编码的编码。

3、request.setCharacterEncoding("UTF-8")的作用是设置对客户端请求进行重新编码的编码。

4、response.setCharacterEncoding("UTF-8")的作用是指定对服务器响应进行重新编码的编码。同时,浏览器也是根据这个参数(附在http响应头中的charset)来对其接收到的数据进行重新编码(或者称为解码)。Html中meta也有个charset,这个是保存本地离线网页时起作用,因为这时没有方法头。

值得注意的是,jsp文件的编码方式:在JSP标准的语法中,如果 pageEncoding属性存在,那么JSP页面的字符编码方式就由pageEncoding决定,否则就由contentType属性中的 charset决定,如果charset也不存在,JSP页面的字符编码方式就采用默认的ISO-8859-1(在eclipse中可以自行配置文件的默认编码方式)。

4 其它

Java编译时,jvm按照系统默认(我们常用的运行环境一般为eclipse或者操作系统,eclipse的默认编码格式可以自己调整;中文操作系统默认使用GBK格式)或者按照指定的字符集(javac –encoding xxx)将源文件转化为unicode格式存储在内存中编译(Java内存中采用unicode编码,一个字符占两字节)。编译后字符数据会以UNICODE格式存入字节码文件中,生成class文件。

在运行过程中,JAVA也是采用UNICODE编码的,并且默认输入和输出的都是操作系统的默认编码。System.getProperty("file.encoding");查看系统默认编码。

在前端,我们可以用JS脚本来对参数编码:encodeURIComponent(),在JAVA端,可以用java.net.URLDecoder.decode来解码。不过这里要注意一个问题,就是TOMCAT会自动先对URL 做一次decode,我们可以在TOMCAT的UDecoder类中看到这一点。不过TOMCAT并非使用了URLDecoder.decode,而是自己编写了一个decode函数。网上有些文章上介绍过一种处理乱码的方法便是在JS中对参数做两次encodeURIComponent,在JAVA中做 一次decode,可以解决一些没有设置URIEncoding时发生的乱码问题。(解释如下图)

5 unicode和utf8

(1) ASCII码,8位,0到127(包括英文字母、标点等),128到255为扩展ASCII

(2) GBK:16位,一个汉字两个字节,一个英文一个字节

(3) Unicode(统一码),编码方案,为全世界每个字符设定唯一的编码。Unicode目前普遍采用的是UCS-2,它用两个字节来编码一个字符。Unicode也有UCS-4规范,就是用 4个字节来编码字符。

(4) utf8:UTF-8是一种unicode的实现方式,它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。,注意的是unicode一个中文字符占2个字节,而UTF-8一个中 文字符占3个字节)。从unicode到uft-8并不是直接的对应,而是要过一些算法和规则来转换。如下图所示。

例1:“汉”字的Unicode编码是0x6C49。0x6C49在0x0800-0xFFFF之间,使用用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将0x6C49写成二进制是:0110 1100 0100 1001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89

javaEE中的字符编码问题的更多相关文章

  1. 浅析白盒审计中的字符编码及SQL注入

    尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范.但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如g ...

  2. 001. Java内存中的字符编码

    Java内存中的字符编码 Unicode字符集及utf-8 .utf-16.utf-32 等字符编码方式 字符集:字符表示的数字集合,元素称为码点或码位: 字符编码:字符实际的储存表示: 码点:一个码 ...

  3. APACHE2.4 指定目录中的字符编码

    APACHE2.4 指定目录中的字符编码 xampp 的 apache2.4 默认字符编码是西文,中文字符显示乱码,在 httpd.conf 没有 AddDefaultCharset utf-8 这样 ...

  4. SpringBoot(八):SpringBoot中配置字符编码 Springboot中文乱码处理

    SpringBoot中配置字符编码一共有两种方式 方式一: 使用传统的Spring提供的字符编码过滤器(和第二种比较,此方式复杂,由于时间原因这里先不介绍了,后续补上) 方式二(推荐使用) 在appl ...

  5. servlet中的字符编码过滤器的使用

    一:简介 Servlet过滤器是客户端和目标资源的中间层组件,主要是用于拦截客户端的请求和响应信息.如当web容器收到一条客户端发来的请求 web容器判断该请求是否与过滤器相关联,如果相关联就交给过滤 ...

  6. .NET Framework 中的字符编码

    字符是可用多种不同方式表示的抽象实体. 字符编码是一种为受支持字符集中的每个字符进行配对的系统,配对时使用的是表示该字符的某些值. 例如,摩尔斯电码是一种为罗马字母表中的每个字符进行配对的字符编码,配 ...

  7. java中的字符编码方式

    1. 问题由来 面试的时候被问到了各种编码方式的区别,结果一脸懵逼,这个地方集中学习一下. 2. 几种字符编码的方式 1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符 ...

  8. linux中修改字符编码

    一. ubuntu修改字符编码 1. 添加字符编码,例如zh_CN.UTF-8,有两种方式 方法1:locale-gen zh_CN.UTF-8   #locale-gen命令只在ubuntu中才有 ...

  9. 关于php开发中的字符编码问题总结的几个要点

    用php这么久,今天终于要彻底总结下php乱码问题,因为实在是吃过不少亏啊 1:header("content-type:text/html;charset=utf-8")或者&l ...

随机推荐

  1. 嵌入式驱动开发之phy---fine Mac与Phy组成原理的简单分析

    关键字rj45.pci-e 1. general 下图是网口结构简图.网口由CPU.MAC和PHY三部分组成.DMA控制器通常属于CPU的一部分,用虚线放在这里是为了表示DMA控制器可能会参与到网口数 ...

  2. 【BZOJ】1680: [Usaco2005 Mar]Yogurt factory(贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1680 看不懂英文.. 题意是有n天,第i天生产的费用是c[i],要生产y[i]个产品,可以用当天的也 ...

  3. C#获取CPU编号

    //System.Management;//需要添加引用(系统自带) /// <summary> /// 获取cpu编号 /// </summary> /// <retu ...

  4. 【Debian】install

    n年前的报废台式机实在不能忍受xp的速度,果断装Linux近期家里的小本装了Ubuntu14.04 ,实在不习惯最新的图形界面.装个debian试试吧. 1.专门弄一个空白分区2.官网下载debian ...

  5. java -Mac搭建本地服务器并映射到外网

    最近在学习Html,小有进步变想着写一个浪漫的静态页面给女朋友浪漫一下,那么问题就来了,如何把我的网页让对网络一窍不通的女朋友看到,所以便想到了是用自己电脑作为服务器的想法.百度以后整理如下: 首先搭 ...

  6. php数据库操作命令精华大全

    1.表结构//列信息2.表数据//行信息3.表索引//把列中的行加到索引中(一般情况下一个表一定要把id这一列的所有数据都加到主键索引中) 2.[dos下]关闭mysql:net stop mysql ...

  7. Linux下wc命令详解

    功能说明:计算字数. 语   法:wc [-clw][--help][--version][文件…] 补充说明:利用wc指令我们可以计算文件的Byte数.字数.或是列数,若不指定任何文件名称,或是所给 ...

  8. Flash Builder 相关

    1.Flex SDK 4.1 兼容性 Flex SDK 4.1 兼容 Flash Builder 4.0 ,因此在 Flash Builder 4.0 中使用 4.1 SDK 时可以使用设计视图 Fl ...

  9. http协议详解(1)

    HTTP协议报文格式 接下来我们看看HTTP协议(Hypertext Transfer Protocol――超文本传输协议)浏览器端(客户端)向WEB服务器端访问页面的过程和HTTP协议报文的格式. ...

  10. 第一个Gradle入门程序

    参考:http://www.importnew.com/15881.html 准备工作 1.gradle编译环境 下载gradle编译包(http://www.gradle.org/downloads ...