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. Batch Normailzation

    转自:http://blog.csdn.net/malefactor/article/details/51476961

  2. python eval() hasattr() getattr() setattr() 函数使用方法详解

    eval() 函数 --- 将字符串str当成有效的表达式来求值并返回计算结果. 语法:eval(source[, globals[, locals]]) ---> value 参数: sour ...

  3. Linux下面 多线程死锁问题的调试

    最近写服务,经常是单进程,多线程的,加了各种锁,很担心出现死锁问题,专门学习了一下死锁问题的诊断. 死锁 (deallocks): 是指两个或两个以上的进程(线程)在执行过程中,因争夺资源而造成的一种 ...

  4. 2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest D Dividing Marbles

    题目大意: 给出一个$N(N <= 2^{22}$),$N$的二进制表示中1的个数不超过4.  一开始有一个集合$S = {N}$, 每次操作可以选择$n\in S \ (n > 1)$, ...

  5. select标签设置只读的方法(下拉框不可选但可传值)

    1. <select id="s1" name="s1" onfocus="this.defaultIndex=this.selectedInd ...

  6. 如何结合IbatisNet的LIST遍历实现模糊查询

    我仿照Java的Spring+Ibatis+Struct用Castle+IBatisNet+Asp.net的开发框架的DAO的基类:BaseSqlMapDao内定义了一个内部类来辅助模糊查询.内部类代 ...

  7. libevent(1)

    很多时候,除了响应事件之外,应用还希望做一定的数据缓冲.比如说,写入数据的时候,通常的运行模式是: l 决定要向连接写入一些数据,把数据放入到缓冲区中 l 等待连接可以写入 l 写入尽量多的数据 l  ...

  8. 系统内部集成测试(System Integration Testing) SIT 用户验收测试(User Acceptance Testing)

    系统内部集成测试(System Integration Testing) SIT 用户验收测试(User Acceptance Testing) UAT SIT在前,UAT在后,UAT测完才可以上线

  9. Jmeter非GUI分布式测试

    增加参数 -r : 指远程将所有agent启动 Eg: jmeter -n -t purang_yyt_uat_bless_1000_2_0.jmx -r -l purang_yyt_uat_bles ...

  10. As of Flume 1.4.0, Avro is the default RPC protocol.

    Flume 1.8.0 Developer Guide — Apache Flume http://flume.apache.org/FlumeDeveloperGuide.html The remo ...