更新時間:2018年12月07日11時39分 來源:傳智播客 瀏覽次數(shù):
# WEB應用中請求和響應的字符集設置
在web應用里,一切操作都是基于請求和響應的。其中,請求表示客戶端向服務端發(fā)送的數(shù)據(jù),響應表示服務端向客戶端返回的數(shù)據(jù)??蛻舳撕头斩酥g的數(shù)據(jù)交互,如果沒有統(tǒng)一的字符集設置,就會導致數(shù)據(jù)亂碼。
本文就客戶端和服務端之間交互時的亂碼問題進行探討和解決。
> 注:本文使用的是Tomcat7.0版本
## 一、一次請求和響應的執(zhí)行流程
在客戶端和服務端的交互過程中,數(shù)據(jù)需要通過網(wǎng)絡進行傳輸,如果數(shù)據(jù)編碼和解碼方式設置不當,就會亂碼。其實亂碼的原因很簡單:編碼解碼方式不一致,就必定會亂碼。那么亂碼的解決方案就很簡單了:編碼和解碼使用相同的字符集。
? 我們有必要先了解一下一次請求和響應的執(zhí)行過程,之后再說如何解決亂碼問題。
![請求和響應流程](.\請求和響應流程.jpg)
如上圖所示,請求流程如下:
```
頁面提交數(shù)據(jù)--->瀏覽器編碼--->服務器把數(shù)據(jù)封裝到request對象里--->我們的Servlet從request獲取數(shù)據(jù)并解碼
這個過程經(jīng)過了:瀏覽器編碼 和 request解碼。只要它們使用的字符集是相同的,那么客戶端傳遞給服務端的數(shù)據(jù)就不會亂碼。
```
響應流程如下:
```
Servlet里使用response編碼并設置數(shù)據(jù)--->服務器把response轉換成HTTP響應--->瀏覽器解碼并顯示數(shù)據(jù)
這個過程經(jīng)過了:response編碼數(shù)據(jù) 和 瀏覽器解碼數(shù)據(jù)。只要它們使用的字符集是相同的,那么服務端傳遞給客戶端的數(shù)據(jù)就不會亂碼。
```
## 二、請求參數(shù)的字符集設置
### 1. 瀏覽器的編碼方式設置
瀏覽器在提交數(shù)據(jù)時,使用的編碼方式是由` `標簽指定的,如下:
```html
```
### 2. request的解碼方式設置
? 服務端使用request對象來接收客戶端傳遞的參數(shù)。但是request默認使用iso-8859-1進行解碼,所以參數(shù)里的中文會亂碼。
? 如果想要得到正常的中文,必須讓request也采用瀏覽器編碼相同的字符集進行解碼,才可以獲取正常的中文。我們頁面上設置的字符集是utf-8,那么就設置request也使用utf-8進行解碼。實現(xiàn)代碼如下:
```java
//指定request使用utf-8進行解碼請求體里的數(shù)據(jù)
request.setCharacterEncoding("utf-8");
//得到的是正常的中文
String name = request.getParameter("name");
```
? 但是以上方法僅適用于POST提交的參數(shù),不適用于GET提交的參數(shù)。因為GET提交的參數(shù)是在請求行里提交的,而請求行只支持iso-8859-1字符集,不支持其它字符集,所以方法無效了。
? 那么GET提交的參數(shù)應該怎么辦呢?不能指定解碼的字符集,但我們可以進行手動轉碼,把亂碼值還原:怎么亂碼的,逆回去就會還原:
```
亂碼過程:頁面utf-8編碼“張三”--->request對象iso-8859-1解碼--->???亂碼值
還原過程:???亂碼值--->iso-8859-1編碼--->utf-8解碼--->張三
```
? 使用Java代碼實現(xiàn)還原過程就是:
```java
//先得到亂碼值
String value = request.getParameter("name");
//使用iso-8859-1編碼
byte[] bytes = value.getBytes("iso-8859-1");
//使用utf-8解碼,得到正常的中文
value = new String(bytes, "utf-8");
```
## 三、響應數(shù)據(jù)的字符集設置
### 1. response的編碼方式設置
response默認使用的是iso-8859-1字符集進行編碼,是不支持中文的。所以如果想要傳輸中文數(shù)據(jù)到客戶端,首先就需要指定response的字符集,然后再向response中設置數(shù)據(jù)。設置方法如下:
```java
response.setCharacterEncoding("utf-8");
response.getWriter().print("李四");
```
設置完成,就可以向response里輸中文數(shù)據(jù)了。但是如果想要這些數(shù)據(jù)在瀏覽器上能夠正常顯示,就需要指定瀏覽器也采用utf-8進行解碼才可以。
### 2. 瀏覽器的解碼方式設置
基本上各大瀏覽器都可以人為指定字符集,來解碼頁面,例如:firefox。可以在菜單-->查看-->文字編碼-->選擇字符集。這個字符集必須要和服務端設置的response字符集相同,我們這里也需要設置為utf-8。
但是給瀏覽器手動指定解碼字符集,是需要一定的編程基礎的,而普通用戶基本無法完成這一操作。所以我們需要使用其它方案來解決響應數(shù)據(jù)的亂碼問題。
### 3. 響應數(shù)據(jù)的字符集最終設置方案
response提供了一個最終的解決方法,既可以設置response編碼的字符集,也可以指定瀏覽器解碼的字符集。一步到位,解決響應數(shù)據(jù)亂碼問題。具體方法如下:
```java
//同時指定response編碼的字符集,和瀏覽器解碼的字符集,都使用utf-8
response.setContentType("text/html;charset=utf-8");
//再設置的中文,瀏覽器就正常顯示了。不需要再進行其它任何額外的操作
response.getWriter().print("李四");
```