轉載於:https://www.cnblogs.com/hackxiyu/p/9046247.html
一個比較優秀的學習http協議的網站: https://developer.mozilla.org/zh-CN/docs/Web/HTTP
一、問題:
做web項目經常提到的一個需求就是頁面的文件下載,那么下載的時候在后台為什么要設置響應消息頭?為什么這樣設置?
二、解決:
1、例子
//設置響應的消息頭response.setContentType("text/html;charset=UTF-8");//設置響應類型中包含文件附件
response.setHeader("Content-Disposition", "attachment; " +
"filename="+new String(AREA_FILE.getBytes("gb2312"), "ISO-8859-1"));
2、setContentType:
它的作用就是,設置客戶端的MIME類型【多類型郵件傳輸協議】,瀏覽器可以根據該類型來指定程序解析對應類型的文件
比如,servlet里寫入了一個
它的默認類型是[text/html]類型,所以返回的是html也可以不設置
包括下載文件的時候,不指定也是可以的,因為后邊還設置了攜帶的響應附件,可以支持文件的下載
也可以指定響應的編碼,讓瀏覽器可以正確的顯示信息
3、setHeader:
它的作用就是設置響應的頭部
Content-Disposition:指明響應的配置信息
attachment:指明包含附件
4、new String(AREA_FILE.getBytes("gb2312"), "ISO-8859-1"))
這里特別說明,如果文件名不包含中文可以不設置該項
如果包含中文名,則需要設置編碼,否則文件名下載后中文字符會亂碼
其中,getBytes指定了編碼的方式,ISO-8859-1指定了解碼(讀取)的方式
想要轉換編碼,就是先編碼,再解碼
如:
utf-8轉gbk :new String(str.getBytes("gbk"), "gbk"))
gbk轉utf-8 :new String(str.getBytes("utf-8"), "utf-8"))
三、擴展:
那么為什么下載的文件名中的中文字符會亂碼?
首先,我們常用的編碼:
(1)ISO-8859-1:它是單字節編碼,tomcat默認的字符編碼方式,但是可以標識的字符量比較少
(2)unicode:單字節編碼
(3)gb2312:我們大中國的漢字編碼,兩個字節標識一個漢字
(4)UTF-8:萬國碼,支持世界字符,是可變的長度編碼,字節數不定
亂碼的出現就是因為,java的字符串默認采用的編碼是unicode編碼,而tomcat傳輸又更改為iso-8859-1,
頁面讀取的時候,碰到漢字本來雙字節的讀取成了單字節,出現了亂碼
所以要把字符串以【gbk】編碼,再以【iso-8859-1】讀取相應的字符,傳遞到頁面就是【iso-8859-1】,可以正常顯示中文字符