JavaEE中用response向客戶(hù)端輸出中文數(shù)據(jù)亂碼問(wèn)題分析
Web服務(wù)器收到客戶(hù)端的http請(qǐng)求,會(huì)針對(duì)每一次請(qǐng)求,分別創(chuàng)建一個(gè)用于代表請(qǐng)求的request對(duì)象,和代表響應(yīng)的response對(duì)象。request和response對(duì)象既然代表請(qǐng)求和響應(yīng),那我們要獲取客戶(hù)機(jī)提交過(guò)來(lái)的數(shù)據(jù),只需要找request對(duì)象就行了。要向客戶(hù)機(jī)輸出數(shù)據(jù),只需要找response對(duì)象就行了。
package com.yyz.response;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//輸出中文的問(wèn)題
public class ResponseDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String data = "中國(guó)";
OutputStream out = response.getOutputStream();
out.write(data.getBytes());
/**
* out.write(data.getBytes());這句代碼涉及兩次查閱碼表。
* "中國(guó)"從字符數(shù)據(jù)變成字節(jié)數(shù)據(jù)的時(shí)候,會(huì)查閱gb2312碼表。
* 數(shù)據(jù)發(fā)送到瀏覽器端要顯示的時(shí)候,需要再次查閱碼表,這時(shí)查閱的碼表與瀏覽器的設(shè)置有關(guān)。
*/
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
瀏覽器編碼設(shè)置為GB2312時(shí)的測(cè)試結(jié)果:

瀏覽器編碼設(shè)置為UTF-8時(shí)的測(cè)試結(jié)果:

為了讓我們的網(wǎng)站能被國(guó)外用戶(hù)訪(fǎng)問(wèn),我們?cè)趯⒆址麛?shù)據(jù)變成字節(jié)數(shù)據(jù)時(shí),要指定轉(zhuǎn)換的碼表為UTF-8。但這時(shí)如果瀏覽器以GB2312打開(kāi),又會(huì)出現(xiàn)亂碼問(wèn)題。雖然可以通過(guò)改變?yōu)g覽器的設(shè)置來(lái)解決這個(gè)亂碼問(wèn)題,但不利于增強(qiáng)用戶(hù)體驗(yàn)。因而我們需要用程序告訴瀏覽器查閱何種碼表顯示數(shù)據(jù)。
package com.yyz.response;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//輸出中文的問(wèn)題
public class ResponseDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//在服務(wù)器端,數(shù)據(jù)是以哪個(gè)碼表輸出的,那么就要控制瀏覽器以哪個(gè)碼表打開(kāi)。
String data = "中國(guó)";
response.setHeader("content-type", "text/html;charset=UTF-8");
OutputStream out = response.getOutputStream();
out.write(data.getBytes("UTF-8"));
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
多學(xué)一招:
使用HTML語(yǔ)言里面的<meta>標(biāo)簽來(lái)控制瀏覽器行為。
<meta http-equiv="Content-type'' content=''text/html;charset=UTF-8">
http-equiv模擬了HTTP的響應(yīng)頭,告訴瀏覽器以UTF-8的碼表打開(kāi)。真正的響應(yīng)頭優(yōu)先于用http-equiv模擬的響應(yīng)頭。
實(shí)際開(kāi)發(fā)中,服務(wù)器向?yàn)g覽器寫(xiě)文本數(shù)據(jù)應(yīng)該用字符流。但是通過(guò)response的getWriter方法拿到的字符流默認(rèn)的碼表是ISO8859-1,這張碼表里是沒(méi)有中文對(duì)應(yīng)的編碼的,因而會(huì)把?對(duì)應(yīng)的編碼發(fā)送給瀏覽器,瀏覽器打開(kāi)后全是問(wèn)號(hào)。通過(guò)response的setCharacterEncoding可以修改服務(wù)端發(fā)送數(shù)據(jù)時(shí)查閱的碼表。
package com.yyz.response;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//輸出中文的問(wèn)題
public class ResponseDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//在服務(wù)器端,數(shù)據(jù)是以哪個(gè)碼表輸出的,那么就要控制瀏覽器以哪個(gè)碼表打開(kāi)。
String data = "中國(guó)";
response.setHeader("content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write(data);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
這里有幾個(gè)小細(xì)節(jié)需要注意:
1. response.setCharacterEncoding("UTF-8");需要寫(xiě)在PrintWriter out = response.getWriter();的前面。拿到字符流后再設(shè)置編碼是沒(méi)有用的。
2. response.setHeader("content-type", "text/html;charset=UTF-8");有一種更為簡(jiǎn)單的寫(xiě)法response.setContentType("text/html;charset=UTF-8");。
3.response.setContentType("text/html;charset=UTF-8");這句代碼其實(shí)有兩個(gè)作用:通知response以UTF-8輸出和瀏覽器以UTF-8打開(kāi)。即等價(jià)于response.setHeader("content-type", "text/html;charset=UTF-8");和response.setCharacterEncoding("UTF-8");兩句代碼。
4.通過(guò)以上閱讀,讀者應(yīng)該能明白為什么response.getOutputStream.write(1);這句代碼在瀏覽器的輸出不是1。因?yàn)闉g覽器是一個(gè)文本編輯器,收到數(shù)據(jù)后會(huì)拿著1去查碼表,然后顯示對(duì)應(yīng)字符。想在瀏覽器輸出數(shù)字,應(yīng)該把數(shù)字變成字符串,response.getOutputStream.write((1+"").getBytes());.
用OutputStream(字節(jié)流)發(fā)送數(shù)據(jù):
1、response.getOutputStream().write(“中國(guó)”.getBytes());//以默認(rèn)編碼發(fā)送數(shù)據(jù)
2、response.getOutputStream().write("中國(guó)".getBytes("UTF-8"));//以UTF-8編碼發(fā)送數(shù)據(jù),瀏覽器(默認(rèn)用GB2312)會(huì)出現(xiàn)亂碼
解決辦法:
2.1通過(guò)更改瀏覽器的編碼方式:IE/”查看”/”編碼”/”UTF-8”(不可取)
2.2通過(guò)設(shè)置響應(yīng)頭告知客戶(hù)端編碼方式:response.setHeader(“Content-type”, “text/html;charset=UTF-8”);//告知瀏覽器數(shù)據(jù)類(lèi)型及編碼
2.3通過(guò)meta標(biāo)簽?zāi)M請(qǐng)求頭:out.write("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />".getBytes());
2.4通過(guò)以下方法:response.setContentType("text/html;charset=UTF-8");
- Java HttpServletResponse響應(yīng)實(shí)現(xiàn)過(guò)程詳解
- java web response提供文件下載功能的實(shí)例講解
- 淺談java分頁(yè)三個(gè)類(lèi) PageBean ResponseUtil StringUtil
- java HttpServletRequest和HttpServletResponse詳解
- java中response對(duì)象用法實(shí)例分析
- JavaEE通過(guò)response實(shí)現(xiàn)請(qǐng)求重定向
- Java response響應(yīng)體和文件下載實(shí)現(xiàn)原理
相關(guān)文章
Java Web導(dǎo)出等比例圖片到Excel的實(shí)現(xiàn)過(guò)程
我們使用Java導(dǎo)出圖片到Excel,打開(kāi)成功導(dǎo)出的Excel一看,商品對(duì)應(yīng)的圖片都很規(guī)矩的按照我的設(shè)置鋪滿(mǎn)了整個(gè)單元格,但是,商品圖片卻都變形了,這樣肯定是不行的,于是第一反應(yīng)就是將圖片等比例導(dǎo)出,所以本文本給大家介紹了如何使用Java Web導(dǎo)出等比例圖片到Excel2023-11-11
Mybatis中自定義TypeHandler處理枚舉的示例代碼
typeHandler,是 MyBatis 中的一個(gè)接口,用于處理數(shù)據(jù)庫(kù)中的特定數(shù)據(jù)類(lèi)型,下面簡(jiǎn)單介紹創(chuàng)建自定義 typeHandler 來(lái)處理枚舉類(lèi)型的示例,感興趣的朋友跟隨小編一起看看吧2024-01-01
詳解jeefast和Mybatis實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)的問(wèn)題
這篇文章主要介紹了詳解jeefast和Mybatis實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)的問(wèn)題,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
通過(guò)實(shí)例了解Spring中@Profile的作用
這篇文章主要介紹了通過(guò)實(shí)例了解Spring中@Profile的作用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
基于java HashMap插入重復(fù)Key值問(wèn)題
這篇文章主要介紹了基于java HashMap插入重復(fù)Key值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
SpringBoot整合MybatisPlus的基本應(yīng)用指南
MyBatis-Plus ,簡(jiǎn)稱(chēng) MP,是一個(gè) MyBatis的增強(qiáng)工具,在 MyBatis 的基礎(chǔ)上只做增強(qiáng)不做改變,下面小編就來(lái)和大家介紹一下SpringBoot整合MybatisPlus的一些基本應(yīng)用吧2025-03-03
SpringBoot啟動(dòng)時(shí)自動(dòng)執(zhí)行sql腳本的方法步驟
本文主要介紹了SpringBoot啟動(dòng)時(shí)自動(dòng)執(zhí)行sql腳本的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09

