最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

HttpServletResponse亂碼問題_動力節(jié)點Java學(xué)院整理

 更新時間:2017年07月25日 10:37:51   作者:fjdingsd  
這篇文章主要介紹了HttpServletResponse亂碼問題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

一個完整的http響應(yīng)包括響應(yīng)行,若干響應(yīng)頭和響應(yīng)數(shù)據(jù)主體三部分構(gòu)成。如果我們能用響應(yīng)對象來進行這三部分的處理,就能向客戶發(fā)送特定的響應(yīng)數(shù)據(jù)包。

先從HttpServletResponse對象的方法中可以看到有如下方法(部分):

這只是一部分,但是我們卻可以看出,通過響應(yīng)對象的方法,我們就能設(shè)置響應(yīng)客戶端數(shù)據(jù)的一些信息。比如setStatus(int sc)方法,我們從HttpServletResponse的API中的字段定義可找到已經(jīng)設(shè)置好的響應(yīng)碼(部分):

我們通過setHeader或者addHeader就能對一些數(shù)據(jù)進行跟客戶端的告知,比如我想讓某個頁面的數(shù)據(jù)在客戶端保存一天,也就是如果客戶端再向我請求的話,則它應(yīng)該去緩存中獲取,直到一天之后才能重新向我請求,那么我就必須使用到了“Expires”響應(yīng)頭,將這個響應(yīng)頭的值設(shè)為一天后的時間告訴給客戶端:

在MyEclipse中的【myservlet】web工程下,創(chuàng)建名為ServletDemo1的Servlet,代碼如下:

 

public class ServletDemo extends HttpServlet {
   public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
 
     long expiresTime = System.currentTimeMillis()+1*24*60*60*1000; //將緩存截止時間設(shè)置為一天后
     response.setDateHeader("expires", expiresTime);
     
   }
 } 

這時候用瀏覽器來訪問這個Servlet(訪問之前最好現(xiàn)將瀏覽器中的緩沖清除干凈),訪問之后我們再來看看這個緩存的頁面文件:

右鍵查看其屬性:

可以看到我們是在9月28日訪問的這個文件,而服務(wù)器已經(jīng)將這個文件的緩沖時間設(shè)置為了29日。

注意:對于”Expires”響應(yīng)頭的設(shè)置必須使用setDateHeader方法,使用setHeader方法無效。

使用響應(yīng)對象可以向客戶端寫入數(shù)據(jù),我們采用獲取響應(yīng)對象的輸出流,將數(shù)據(jù)用write方法寫,這些數(shù)據(jù)是寫入到響應(yīng)對象中,而服務(wù)器再將這些響應(yīng)對象回傳給客戶端進行解析。而這些數(shù)據(jù)在響應(yīng)對象中正是處于HTTP協(xié)議的響應(yīng)數(shù)據(jù)實體中。

通過HttpServletResponse對象的父類ServletResponse對象的getOutputStream方法和getWriter方法可以獲取向響應(yīng)對象的數(shù)據(jù)實體中寫入數(shù)據(jù)。這里如果傳送的是英文數(shù)據(jù)一般都沒有什么問題,而中文編碼則是會令人頭疼的。

首先我們來看響應(yīng)對象的getOutputStream方法,我們在一個Servlet程序中代碼如下:

   String data = "銀魂";
   OutputStream out = response.getOutputStream();
   out.write(data.getBytes());

而在瀏覽器中訪問這個Servlet,看到的是:

是的,沒有出現(xiàn)亂碼的問題,這主要有兩點原因:

一個是瀏覽器本身的解碼方式是根據(jù)平臺語言環(huán)境來設(shè)置的,我的操作系統(tǒng)是Windows的中文版本,因此瀏覽器的解碼采用的編碼表為“GB2312”:

另一個原因是因為,在將字符串轉(zhuǎn)為字節(jié)數(shù)組時,采用了getBytes()方法,這個方法在String類的API文檔中明確說明了采用平臺默認(rèn)的字符集,根據(jù)我的系統(tǒng)這個方法也采用了“GB2312”編碼表。

因此服務(wù)器編碼和客戶端解碼都采用同一編碼表這就不會出現(xiàn)中文亂碼問題。

如果我在getBytes方法中采用UTF-8編碼,那么結(jié)果自然會出錯:

   String data = "銀魂";
   OutputStream out = response.getOutputStream();
   out.write(data.getBytes("UTF-8"));

除非你也在瀏覽器中更改編碼方式,改成UTF-8就可以重新看到正確的中文數(shù)據(jù)了:

當(dāng)然這肯定不適合給用戶這么操作,畢竟不是誰都懂瀏覽器的編碼。

如果我們一定要將中文數(shù)據(jù)采用“UTF-8”的方式(UTF-8有利于國際化),有這么兩種解決采用UTF-8編碼方式的中文亂碼問題:

第一種解決方式:使用HttpServletResponse響應(yīng)對象的setHeader的方法,將“Content-type”這個響應(yīng)頭中設(shè)置編碼方式。同時,sun公司也提供了更便捷的代碼語句setContentType給編程人員使用。

在Servlet中的代碼:

   response.setHeader("content-type", "text/html;charset=UTF-8");
   //response.setContentType("text/html;charset=UTF-8");  //這句功能同上一句
   String data = "銀魂";
   OutputStream out = response.getOutputStream();
   out.write(data.getBytes("UTF-8"));

這樣在瀏覽器中可以看到正確的中文數(shù)據(jù),并且瀏覽器自動將編碼方式采用UTF-8:

附帶從HttpWatch中觀察到的數(shù)據(jù)包:

注意:如果response.setHeader("content-type", "text/html;charset=UTF-8");中將"text/html;charset=UTF-8"中的分號“;”寫成了逗號“,”就會變成下載該Servlet文件。

所以書寫要注意。

第二種解決方式:我們不直接在響應(yīng)對象中設(shè)置“Content-type”這個響應(yīng)頭,而是通過HTML的<meta>標(biāo)簽,該標(biāo)簽的作用就是模擬一個響應(yīng)頭,這樣在回傳的響應(yīng)對象中,某些響應(yīng)頭就不會被設(shè)置,但是還是有這個響應(yīng)頭的功能,例如我們在HTML頁面中經(jīng)常能見到的<meta http-equiv="content-type" content="text/html;charset=utf-8">這個標(biāo)簽,是不是和第一種方式很像。相關(guān)代碼為:

   String data = "銀魂";
   OutputStream out = response.getOutputStream();
   out.write("<meta http-equiv='content-type' content='text/html;charset=utf-8'>".getBytes());
   out.write(data.getBytes("UTF-8"));

這時候在瀏覽器中同樣能觀察到正確的中文數(shù)據(jù),同時可以看到瀏覽器已經(jīng)自動采用“UTF-8”編碼方式:

同時,在瀏覽器瀏覽源代碼和觀察HttpWatch窗口:

從上面可以看出,服務(wù)器發(fā)回的響應(yīng)中沒有“Content-type”這個響應(yīng)頭,但是在響應(yīng)數(shù)據(jù)實體中有<meta>標(biāo)簽,瀏覽器能解析這個HTML語言,得到這個標(biāo)簽中設(shè)置的“Content-type”模擬響應(yīng)頭,因此能根據(jù)這個模擬響應(yīng)頭中的編碼方式來設(shè)置瀏覽器應(yīng)該采用的碼表。

如果我們用輸出流直接輸出數(shù)字的話,會是輸出這個數(shù)字在編碼表中代表的字符,如代碼為:

 public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
     
    response.getOutputStream().write(97);
   }  

在瀏覽器中得到:a。

說完了從響應(yīng)對象中得到OutputSteam對象,接著我們來討論從響應(yīng)對象中得到Writer對象,眾所周知,字符流是由字節(jié)流加編碼表組成,那么在響應(yīng)對象中的字符流采用什么編碼表方式呢?我們來看看HttpServletResponse對象的getWriter()方法的API手冊說明:

從這里面看出如果沒有為這個getWriter()方法設(shè)置編碼表,那么則默認(rèn)采用 “ISO-8859-1”編碼表?;蛘卟捎庙憫?yīng)對象的getCharacterEncoding()方法查看也可以。

那么在服務(wù)器端如果要改變對封裝數(shù)據(jù)的編碼格式可以有兩種方式:

第一種:使用響應(yīng)對象的setCharacterEncoding()方法來設(shè)置服務(wù)器采用的編碼表,接著使用setContendType或者setHeader告知客戶端服務(wù)器采用的編碼表,后者在上面已經(jīng)說過。

示例代碼:

 public class ServletResponse extends HttpServlet {
 
   public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
     
     response.setCharacterEncoding("UTF-8");
     response.setContentType("text/html;charset=UTF-8");
     PrintWriter writer = response.getWriter();
     String data = "銀魂";
     writer.write(data);  
   }
 }

注意,光只有setCharacterEncoding()方法只能改變服務(wù)器端采用的編碼表,而沒能通知客戶端,所以需要setContentType設(shè)置“Content-type”響應(yīng)頭,或者如之前所說的寫入<meta>標(biāo)簽來模擬“Content-type”響應(yīng)頭。

第二種:直接使用setContentType方法,通過這種方法,可以在服務(wù)器和客戶端同時設(shè)置編碼表,也就是第一種方式中兩個方法的結(jié)合,因此上述示例的代碼如下:

 public void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
     response.setContentType("text/html;charset=UTF-8");
     
     PrintWriter writer = response.getWriter();
     String data = "銀魂";
     writer.write(data);  
 }
 }

以上分別從響應(yīng)對象HttpServletResponse中根據(jù)獲取的字節(jié)流或者字符流向客戶端輸出數(shù)據(jù)時會碰到的中文亂碼問題做出了分析和解決。

相關(guān)文章

  • IDEA在一個項目空間下管理多個項目的操作方法

    IDEA在一個項目空間下管理多個項目的操作方法

    這篇文章主要介紹了IDEA如何在一個項目空間下管理多個項目,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Java數(shù)學(xué)工具類MathUtil詳解

    Java數(shù)學(xué)工具類MathUtil詳解

    這篇文章主要為大家詳細(xì)介紹了Java數(shù)學(xué)工具類MathUtil的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 基于Redis分布式鎖Redisson及SpringBoot集成Redisson

    基于Redis分布式鎖Redisson及SpringBoot集成Redisson

    這篇文章主要介紹了基于Redis分布式鎖Redisson及SpringBoot集成Redisson,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小小伙伴可以參考一下
    2022-09-09
  • 如何編寫javascript的gulp插件

    如何編寫javascript的gulp插件

    本文主要介紹了使用PMD進行代碼審查的方法,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • IntelliJ IDEA 2021.1 EAP 1 發(fā)布支持 Java 16 和 WSL 2

    IntelliJ IDEA 2021.1 EAP 1 發(fā)布支持 Java 16 和 WSL 2

    這篇文章主要介紹了IntelliJ IDEA 2021.1 EAP 1 發(fā)布支持 Java 16 和 WSL 2,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • java 根據(jù)前端返回的字段名進行查詢數(shù)據(jù)

    java 根據(jù)前端返回的字段名進行查詢數(shù)據(jù)

    本文介紹了如何在Java中使用SpringDataJPA實現(xiàn)動態(tài)查詢功能,以便根據(jù)前端傳遞的字段名動態(tài)構(gòu)建查詢語句,通過創(chuàng)建實體類、Repository接口、構(gòu)建動態(tài)查詢、在Service層和Controller中使用動態(tài)查詢,實現(xiàn)了前后端分離架構(gòu)中的靈活查詢需求
    2024-11-11
  • Spring中的Sentinel熔斷降級詳解

    Spring中的Sentinel熔斷降級詳解

    這篇文章主要介紹了Spring中的Sentinel熔斷降級詳解,熔斷降級是一種保護系統(tǒng)穩(wěn)定性和可用性的機制,旨在防止故障的擴散和蔓延,提高用戶體驗和信任度,需要的朋友可以參考下
    2023-09-09
  • SpringBoot應(yīng)用快速部署到K8S的詳細(xì)教程

    SpringBoot應(yīng)用快速部署到K8S的詳細(xì)教程

    這篇文章主要介紹了SpringBoot應(yīng)用快速部署到K8S的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • mybatis錯誤之in查詢?<foreach>循環(huán)問題

    mybatis錯誤之in查詢?<foreach>循環(huán)問題

    這篇文章主要介紹了mybatis錯誤之in查詢?<foreach>循環(huán)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java避免死鎖_動力節(jié)點Java學(xué)院整理

    Java避免死鎖_動力節(jié)點Java學(xué)院整理

    在有些情況下死鎖是可以避免的。本文將展示三種用于避免死鎖的技術(shù)。對java避免死鎖的相關(guān)知識感興趣的朋友一起通過本文學(xué)習(xí)吧
    2017-06-06

最新評論

固阳县| 镇巴县| 常山县| 长寿区| 五原县| 成安县| 武平县| 武平县| 高密市| 墨江| 安西县| 鄂温| 深泽县| 郁南县| 廊坊市| 麻栗坡县| 宜兴市| 吴旗县| 无棣县| 那曲县| 财经| 湖口县| 富顺县| 广灵县| 锡林郭勒盟| 葵青区| 马山县| 醴陵市| 蕉岭县| 清镇市| 馆陶县| 吉木乃县| 台前县| 邵阳县| 海阳市| 江达县| 聂荣县| 雅江县| 石屏县| 邵阳市| 高淳县|