一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - HttpServletResponse亂碼問題_動力節點Java學院整理

HttpServletResponse亂碼問題_動力節點Java學院整理

2020-12-06 15:23fjdingsd Java教程

這篇文章主要介紹了HttpServletResponse亂碼問題,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

一個完整的http響應包括響應行,若干響應頭和響應數據主體三部分構成。如果我們能用響應對象來進行這三部分的處理,就能向客戶發送特定的響應數據包。

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

HttpServletResponse亂碼問題_動力節點Java學院整理

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

HttpServletResponse亂碼問題_動力節點Java學院整理

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

在myeclipse中的【myservlet】web工程下,創建名為servletdemo1的servlet,代碼如下:

 

?
1
2
3
4
5
6
7
8
9
public class servletdemo extends httpservlet {
   public void doget(httpservletrequest request, httpservletresponse response)
       throws servletexception, ioexception {
 
     long expirestime = system.currenttimemillis()+1*24*60*60*1000; //將緩存截止時間設置為一天后
     response.setdateheader("expires", expirestime);
     
   }
 } 

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

HttpServletResponse亂碼問題_動力節點Java學院整理

右鍵查看其屬性:

HttpServletResponse亂碼問題_動力節點Java學院整理

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

注意:對于”expires”響應頭的設置必須使用setdateheader方法,使用setheader方法無效。

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

通過httpservletresponse對象的父類servletresponse對象的getoutputstream方法和getwriter方法可以獲取向響應對象的數據實體中寫入數據。這里如果傳送的是英文數據一般都沒有什么問題,而中文編碼則是會令人頭疼的。

首先我們來看響應對象的getoutputstream方法,我們在一個servlet程序中代碼如下:

?
1
2
3
string data = "銀魂";
outputstream out = response.getoutputstream();
out.write(data.getbytes());

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

HttpServletResponse亂碼問題_動力節點Java學院整理

是的,沒有出現亂碼的問題,這主要有兩點原因:

一個是瀏覽器本身的解碼方式是根據平臺語言環境來設置的,我的操作系統是windows的中文版本,因此瀏覽器的解碼采用的編碼表為“gb2312”:

HttpServletResponse亂碼問題_動力節點Java學院整理

另一個原因是因為,在將字符串轉為字節數組時,采用了getbytes()方法,這個方法在string類的api文檔中明確說明了采用平臺默認的字符集,根據我的系統這個方法也采用了“gb2312”編碼表。

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

如果我在getbytes方法中采用utf-8編碼,那么結果自然會出錯:

?
1
2
3
string data = "銀魂";
outputstream out = response.getoutputstream();
out.write(data.getbytes("utf-8"));

HttpServletResponse亂碼問題_動力節點Java學院整理

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

HttpServletResponse亂碼問題_動力節點Java學院整理

HttpServletResponse亂碼問題_動力節點Java學院整理

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

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

第一種解決方式:使用httpservletresponse響應對象的setheader的方法,將“content-type”這個響應頭中設置編碼方式。同時,sun公司也提供了更便捷的代碼語句setcontenttype給編程人員使用。

在servlet中的代碼:

?
1
2
3
4
5
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"));

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

HttpServletResponse亂碼問題_動力節點Java學院整理

附帶從httpwatch中觀察到的數據包:

HttpServletResponse亂碼問題_動力節點Java學院整理

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

所以書寫要注意。

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

?
1
2
3
4
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"));

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

HttpServletResponse亂碼問題_動力節點Java學院整理

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

HttpServletResponse亂碼問題_動力節點Java學院整理

從上面可以看出,服務器發回的響應中沒有“content-type”這個響應頭,但是在響應數據實體中有<meta>標簽,瀏覽器能解析這個html語言,得到這個標簽中設置的“content-type”模擬響應頭,因此能根據這個模擬響應頭中的編碼方式來設置瀏覽器應該采用的碼表。

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

?
1
2
3
4
5
public void doget(httpservletrequest request, httpservletresponse response)
      throws servletexception, ioexception {
    
   response.getoutputstream().write(97);
  }

在瀏覽器中得到:a。

說完了從響應對象中得到outputsteam對象,接著我們來討論從響應對象中得到writer對象,眾所周知,字符流是由字節流加編碼表組成,那么在響應對象中的字符流采用什么編碼表方式呢?我們來看看httpservletresponse對象的getwriter()方法的api手冊說明:

HttpServletResponse亂碼問題_動力節點Java學院整理

從這里面看出如果沒有為這個getwriter()方法設置編碼表,那么則默認采用 “iso-8859-1”編碼表。或者采用響應對象的getcharacterencoding()方法查看也可以。

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

第一種:使用響應對象的setcharacterencoding()方法來設置服務器采用的編碼表,接著使用setcontendtype或者setheader告知客戶端服務器采用的編碼表,后者在上面已經說過。

示例代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
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()方法只能改變服務器端采用的編碼表,而沒能通知客戶端,所以需要setcontenttype設置“content-type”響應頭,或者如之前所說的寫入<meta>標簽來模擬“content-type”響應頭。

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

?
1
2
3
4
5
6
7
8
9
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); 
}
}

以上分別從響應對象httpservletresponse中根據獲取的字節流或者字符流向客戶端輸出數據時會碰到的中文亂碼問題做出了分析和解決。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品一在线观看 | 日本丰满www色 | 短篇小说肉 | 韩国最新理论三级在线观看 | 国产成人亚洲综合a∨婷婷 国产成人亚洲精品乱码在线观看 | 探花国产 | 国产精品99爱免费视频 | 日韩欧美一区二区三区免费看 | 国产高清专区 | 无人区1免费完整观看 | 色姑娘导航 | 国产麻豆成91 | 狠狠色伊人亚洲综合网站色 | japanese在线观看| 疯狂伦交1一6 小说 风间由美在线 | ffee性xxⅹ另类老妇hd | 免费看黄色片的网站 | 亚洲视频免费在线看 | 久久强奷乱码老熟女 | 国产第一综合另类色区奇米 | 男人搡女人视频免费看 | 国产一区二区播放 | 亚洲成片在线看 | 晓雪老师我要进你里面好爽 | 成人啪啪漫画全文阅读 | 公翁的舌尖研磨她的花蒂小说 | 国产成人精品一区 | 国内精品免费一区二区三区 | 日本一道高清不卡免费 | 国产欧美日韩不卡一区二区三区 | 波多野结衣中文丝袜字幕 | 国产91青青成人a在线 | 91麻豆精东果冻天美传媒老狼 | avav男人天堂 | 五月婷婷俺也去开心 | 国产自拍影院 | ipx-177绝对领域在线观看 | 成年性香蕉漫画在线观看 | 精品国产乱码久久久久久免费流畅 | 青青草原手机在线视频 | 男人天堂网在线 |