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

全國(guó)咨詢/投訴熱線:400-618-4000

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

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

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

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

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

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

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

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

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

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

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

如上圖所示,請(qǐng)求流程如下:

```

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

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

```

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

```

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

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

```

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

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

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

```html

```

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

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

? 如果想要得到正常的中文,必須讓request也采用瀏覽器編碼相同的字符集進(jìn)行解碼,才可以獲取正常的中文。我們頁(yè)面上設(shè)置的字符集是utf-8,那么就設(shè)置request也使用utf-8進(jìn)行解碼。實(shí)現(xiàn)代碼如下:

```java

//指定request使用utf-8進(jìn)行解碼請(qǐng)求體里的數(shù)據(jù)

request.setCharacterEncoding("utf-8");

//得到的是正常的中文

String name = request.getParameter("name");

```

? 但是以上方法僅適用于POST提交的參數(shù),不適用于GET提交的參數(shù)。因?yàn)镚ET提交的參數(shù)是在請(qǐng)求行里提交的,而請(qǐng)求行只支持iso-8859-1字符集,不支持其它字符集,所以方法無(wú)效了。

? 那么GET提交的參數(shù)應(yīng)該怎么辦呢?不能指定解碼的字符集,但我們可以進(jìn)行手動(dòng)轉(zhuǎn)碼,把亂碼值還原:怎么亂碼的,逆回去就會(huì)還原:

```

亂碼過(guò)程:頁(yè)面utf-8編碼“張三”--->request對(duì)象iso-8859-1解碼--->???亂碼值

還原過(guò)程:???亂碼值--->iso-8859-1編碼--->utf-8解碼--->張三

```

? 使用Java代碼實(shí)現(xiàn)還原過(guò)程就是:

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

```java

response.setCharacterEncoding("utf-8");

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

```

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

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

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

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

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

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

```java

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

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

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

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

```

0 分享到:
和我們?cè)诰€交談!