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. 2017 ACM区域赛(南宁站) 参赛流水账

    day0: 早上四点起床赶飞机,还好没有吵醒室友导致被打死.本来想在飞机上准备一下下周的小测,结果飞机一点都不平稳,只能全程和队友吹逼聊天.下午在宾馆里和johann通关了一部合金弹头,重温了童年的经 ...

  2. 添加RichEdit控件后导致MFC对话框程序无法运行的解决方法

    新建一个基于对话框的MFC程序,对话框上添加了RichEdit控件,编译成功后无法运行起来,Debug版本与Release版本均不行! Windbg分析结果: WARNING: Stack unwin ...

  3. java三大框架SSH(Struts2 Spring Hibernate)

    http://www.cnblogs.com/qiuzhongyang/p/3874149.html

  4. 监视EF生成SQL的方法(log , SqlServerProfile)

    大家在学习entityframework的时候,都知道那linq写的叫一个爽,再也不用区分不同RDMS的sql版本差异了,但是呢,高效率带来了差灵活性,我们 无法控制sql的生成策略,所以必须不要让自 ...

  5. java项目学习

    GitHub地址:https://github.com/zhanglei-workspace/shopping-management-system

  6. 解决Ajax请求跨域问题

    from:https://blog.csdn.net/wang379275614/article/details/53333775 上篇文章提到,由于浏览器的同源策略,使得,AJAX请求只能发给同源的 ...

  7. Ajax实现验证码异步校验

    验证码异步校验可以防止表单提交后因验证码不正确导致已填的其它项都清空. 整个过程图如下 验证码输入框出代码 <div class="form-group"> <l ...

  8. Python调用外部程序

    通过os.system和subprocess.call()函数调用其他程序 预备知识:cmd中打开和关闭程序 cmd中打开程序 a.打开系统自带程序 系统自带的程序的路径一般都已加入环境变量之中,只需 ...

  9. 【BZOJ4547】Hdu5171 小奇的集合 矩阵乘法

    [BZOJ4547]Hdu5171 小奇的集合 Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值.(数据保证这 ...

  10. 【IDEA】重装基本设置+插件安装

    基本配置:2.1 显示:2.1.1.选中展示Toolbar2.1.2.显示内存占用:2.1.3.显示行号和方法线:2.1.4.代码软分行:2.2.修改快捷键:2.2.1 修改Ctrl + D 快捷键: ...