教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

WEB應(yīng)用的請求和響應(yīng)字符集設(shè)置

更新時間:2018年12月07日11時39分 來源:傳智播客 瀏覽次數(shù):

# WEB應(yīng)用中請求和響應(yīng)的字符集設(shè)置

在web應(yīng)用里,一切操作都是基于請求和響應(yīng)的。其中,請求表示客戶端向服務(wù)端發(fā)送的數(shù)據(jù),響應(yīng)表示服務(wù)端向客戶端返回的數(shù)據(jù)??蛻舳撕头?wù)端之間的數(shù)據(jù)交互,如果沒有統(tǒng)一的字符集設(shè)置,就會導致數(shù)據(jù)亂碼。

本文就客戶端和服務(wù)端之間交互時的亂碼問題進行探討和解決。

web應(yīng)用的請求和相應(yīng)字符集設(shè)置

> 注:本文使用的是Tomcat7.0版本

## 一、一次請求和響應(yīng)的執(zhí)行流程

在客戶端和服務(wù)端的交互過程中,數(shù)據(jù)需要通過網(wǎng)絡(luò)進行傳輸,如果數(shù)據(jù)編碼和解碼方式設(shè)置不當,就會亂碼。其實亂碼的原因很簡單:編碼解碼方式不一致,就必定會亂碼。那么亂碼的解決方案就很簡單了:編碼和解碼使用相同的字符集。

? 我們有必要先了解一下一次請求和響應(yīng)的執(zhí)行過程,之后再說如何解決亂碼問題。

![請求和響應(yīng)流程](.\請求和響應(yīng)流程.jpg)

如上圖所示,請求流程如下:

```

頁面提交數(shù)據(jù)--->瀏覽器編碼--->服務(wù)器把數(shù)據(jù)封裝到request對象里--->我們的Servlet從request獲取數(shù)據(jù)并解碼

這個過程經(jīng)過了:瀏覽器編碼 和 request解碼。只要它們使用的字符集是相同的,那么客戶端傳遞給服務(wù)端的數(shù)據(jù)就不會亂碼。

```

響應(yīng)流程如下:

```

Servlet里使用response編碼并設(shè)置數(shù)據(jù)--->服務(wù)器把response轉(zhuǎn)換成HTTP響應(yīng)--->瀏覽器解碼并顯示數(shù)據(jù)

這個過程經(jīng)過了:response編碼數(shù)據(jù) 和 瀏覽器解碼數(shù)據(jù)。只要它們使用的字符集是相同的,那么服務(wù)端傳遞給客戶端的數(shù)據(jù)就不會亂碼。

```

## 二、請求參數(shù)的字符集設(shè)置

### 1. 瀏覽器的編碼方式設(shè)置

瀏覽器在提交數(shù)據(jù)時,使用的編碼方式是由` `標簽指定的,如下:

```html

```

### 2. request的解碼方式設(shè)置

? 服務(wù)端使用request對象來接收客戶端傳遞的參數(shù)。但是request默認使用iso-8859-1進行解碼,所以參數(shù)里的中文會亂碼。

? 如果想要得到正常的中文,必須讓request也采用瀏覽器編碼相同的字符集進行解碼,才可以獲取正常的中文。我們頁面上設(shè)置的字符集是utf-8,那么就設(shè)置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ù)應(yīng)該怎么辦呢?不能指定解碼的字符集,但我們可以進行手動轉(zhuǎn)碼,把亂碼值還原:怎么亂碼的,逆回去就會還原:

```

亂碼過程:頁面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");

```

## 三、響應(yīng)數(shù)據(jù)的字符集設(shè)置

### 1. response的編碼方式設(shè)置

response默認使用的是iso-8859-1字符集進行編碼,是不支持中文的。所以如果想要傳輸中文數(shù)據(jù)到客戶端,首先就需要指定response的字符集,然后再向response中設(shè)置數(shù)據(jù)。設(shè)置方法如下:

```java

response.setCharacterEncoding("utf-8");

response.getWriter().print("李四");

```

設(shè)置完成,就可以向response里輸中文數(shù)據(jù)了。但是如果想要這些數(shù)據(jù)在瀏覽器上能夠正常顯示,就需要指定瀏覽器也采用utf-8進行解碼才可以。

### 2. 瀏覽器的解碼方式設(shè)置

基本上各大瀏覽器都可以人為指定字符集,來解碼頁面,例如:firefox??梢栽诓藛?->查看-->文字編碼-->選擇字符集。這個字符集必須要和服務(wù)端設(shè)置的response字符集相同,我們這里也需要設(shè)置為utf-8。

但是給瀏覽器手動指定解碼字符集,是需要一定的編程基礎(chǔ)的,而普通用戶基本無法完成這一操作。所以我們需要使用其它方案來解決響應(yīng)數(shù)據(jù)的亂碼問題。

### 3. 響應(yīng)數(shù)據(jù)的字符集最終設(shè)置方案

response提供了一個最終的解決方法,既可以設(shè)置response編碼的字符集,也可以指定瀏覽器解碼的字符集。一步到位,解決響應(yīng)數(shù)據(jù)亂碼問題。具體方法如下:

```java

//同時指定response編碼的字符集,和瀏覽器解碼的字符集,都使用utf-8

response.setContentType("text/html;charset=utf-8");

//再設(shè)置的中文,瀏覽器就正常顯示了。不需要再進行其它任何額外的操作

response.getWriter().print("李四");

```

0 分享到:
和我們在線交談!