更新时间:2018年12月07日11时39分 来源:传智播客 浏览次数:
# WEB应用中请求和响应的字符集设置
在web应用里,一切操作都是基于请求和响应的。其中,请求表示客户端向服务端发送的数据,响应表示服务端向客户端返回的数据。客户端和服务端之间的数据交互,如果没有统一的字符集设置,就会导致数据乱码。
本文就客户端和服务端之间交互时的乱码问题进行探讨和解决。
> 注:本文使用的是Tomcat7.0版本
## 一、一次请求和响应的执行流程
在客户端和服务端的交互过程中,数据需要通过网络进行传输,如果数据编码和解码方式设置不当,就会乱码。其实乱码的原因很简单:编码解码方式不一致,就必定会乱码。那么乱码的解决方案就很简单了:编码和解码使用相同的字符集。
我们有必要先了解一下一次请求和响应的执行过程,之后再说如何解决乱码问题。
![请求和响应流程](.\请求和响应流程.jpg)
如上图所示,请求流程如下:
```
页面提交数据--->浏览器编码--->服务器把数据封装到request对象里--->我们的Servlet从request获取数据并解码
这个过程经过了:浏览器编码 和 request解码。只要它们使用的字符集是相同的,那么客户端传递给服务端的数据就不会乱码。
```
响应流程如下:
```
Servlet里使用response编码并设置数据--->服务器把response转换成HTTP响应--->浏览器解码并显示数据
这个过程经过了:response编码数据 和 浏览器解码数据。只要它们使用的字符集是相同的,那么服务端传递给客户端的数据就不会乱码。
```
## 二、请求参数的字符集设置
### 1. 浏览器的编码方式设置
浏览器在提交数据时,使用的编码方式是由` `标签指定的,如下:
```html
```
### 2. request的解码方式设置
服务端使用request对象来接收客户端传递的参数。但是request默认使用iso-8859-1进行解码,所以参数里的中文会乱码。
如果想要得到正常的中文,必须让request也采用浏览器编码相同的字符集进行解码,才可以获取正常的中文。我们页面上设置的字符集是utf-8,那么就设置request也使用utf-8进行解码。实现代码如下:
```java
//指定request使用utf-8进行解码请求体里的数据
request.setCharacterEncoding("utf-8");
//得到的是正常的中文
String name = request.getParameter("name");
```
但是以上方法仅适用于POST提交的参数,不适用于GET提交的参数。因为GET提交的参数是在请求行里提交的,而请求行只支持iso-8859-1字符集,不支持其它字符集,所以方法无效了。
那么GET提交的参数应该怎么办呢?不能指定解码的字符集,但我们可以进行手动转码,把乱码值还原:怎么乱码的,逆回去就会还原:
```
乱码过程:页面utf-8编码“张三”--->request对象iso-8859-1解码--->???乱码值
还原过程:???乱码值--->iso-8859-1编码--->utf-8解码--->张三
```
使用Java代码实现还原过程就是:
```java
//先得到乱码值
String value = request.getParameter("name");
//使用iso-8859-1编码
byte[] bytes = value.getBytes("iso-8859-1");
//使用utf-8解码,得到正常的中文
value = new String(bytes, "utf-8");
```
## 三、响应数据的字符集设置
### 1. response的编码方式设置
response默认使用的是iso-8859-1字符集进行编码,是不支持中文的。所以如果想要传输中文数据到客户端,首先就需要指定response的字符集,然后再向response中设置数据。设置方法如下:
```java
response.setCharacterEncoding("utf-8");
response.getWriter().print("李四");
```
设置完成,就可以向response里输中文数据了。但是如果想要这些数据在浏览器上能够正常显示,就需要指定浏览器也采用utf-8进行解码才可以。
### 2. 浏览器的解码方式设置
基本上各大浏览器都可以人为指定字符集,来解码页面,例如:firefox。可以在菜单-->查看-->文字编码-->选择字符集。这个字符集必须要和服务端设置的response字符集相同,我们这里也需要设置为utf-8。
但是给浏览器手动指定解码字符集,是需要一定的编程基础的,而普通用户基本无法完成这一操作。所以我们需要使用其它方案来解决响应数据的乱码问题。
### 3. 响应数据的字符集最终设置方案
response提供了一个最终的解决方法,既可以设置response编码的字符集,也可以指定浏览器解码的字符集。一步到位,解决响应数据乱码问题。具体方法如下:
```java
//同时指定response编码的字符集,和浏览器解码的字符集,都使用utf-8
response.setContentType("text/html;charset=utf-8");
//再设置的中文,浏览器就正常显示了。不需要再进行其它任何额外的操作
response.getWriter().print("李四");
```