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

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

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

服務器之家 - 編程語言 - Java教程 - Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

2021-01-31 17:10肖國棟的i自留地 Java教程

本篇文章主要介紹了Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼,探討了 PrintWriter 的缺省編碼與普通字符流的缺省編碼的差異,具有一定的參考價值,有興趣的可以了解一下

在前面的網頁中的編碼與亂碼系列中,曾多次提到使用 servlet 方式構建的動態(tài)響應流,不過在那里都是直接使用字節(jié)流的方式,不過,更為常見的方式是使用字符流。而在前面,又談到了 java 字節(jié)流與字符流的話題。

有了前面的基礎,現(xiàn)在來說下 java servlet 中使用字符流,也即是 printwriter 時的編碼與亂碼問題。

回顧字節(jié)流的情形

先回顧一下,在之前的字節(jié)流響應中,我們使用 string.getbytes 方法,然后總是顯式傳入編碼的參數(shù),使它與 meta 中或者 header 的聲明一致。比如這樣:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

或者這樣:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

只要保持了一致,就不用擔心發(fā)生亂碼的問題。

使用 printwriter 字符流,缺省編碼

現(xiàn)在假如使用 printwriter 來作為響應呢?比如這樣:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

代碼中并沒有顯式傳入什么編碼的參數(shù),不像 string.getbytes 那樣。另一方面,我們知道,字符流最終還是要轉換成字節(jié)流,可是它到底使用了什么編碼呢?是不是 charset.defaultcharset 中的值呢?

就以上述代碼為例,假如現(xiàn)在在瀏覽器中查看,會發(fā)現(xiàn)結果是這樣的:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

可見 defaultcharset 缺省是 utf-8,前面說過,這其實來自于啟動 tomcat server 時所傳入的參數(shù) –dfile.encoding:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

但漢字卻沒有正確輸出,可見 printwriter 并沒有采用這個缺省值。查看 header 中的響應:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

也沒有任何編碼的指示。

雖然 meta 中聲明是 utf-8,輸出的缺省字符集的值也是 utf-8,可是從最終結果不難看出 printwriter 并沒有采納這個值來轉換字節(jié)流。(實際上它根本不會試圖去理解這個)。

看一看它的文檔說明,會發(fā)現(xiàn)情況有點不一樣:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

原來沒有指定時,printwriter 不是用 charset.defaultcharset 中的值,而是用 response.getcharacterencoding 方法中所返回的值,而沒有指定的話,那個方法其實就返回一個缺省值:iso-8859-1。

再看看 getcharacterencoding 方法:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

可以看到它的值又是來源于顯式的 response.setcharacterencoding 或 response.setcontenttype 方法,或者是隱式的 setlocale 方法。(顯式的具有更高的優(yōu)先級)假如沒有,就用缺省的 iso-8859-1。

它還提到 rfc 2047 標準 ,打開看看,是關于 mime 中非 ascii 文本的消息頭擴展(mime (multipurpose internet mail extensions) part three:  message header extensions for non-ascii text)的。文中有一處提到如果字符集編碼缺失,推薦用 iso8859 系列:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

注意這里沒有明說是 iso-8859-1,它說的是 iso-8859-*,不過 servlet 最終采用的是 iso-8859-1.

所以現(xiàn)在清楚了,缺省用 iso-8859-1,可以用 getcharacterencoding 得到它的值,不過 iso 不支持中文字符,所以響應流中不能出現(xiàn)中文:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

結果是這樣:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

使用 printwriter 字符流,顯式指定編碼

按照前面說的,可以在 write 之前使用 setcharacterencoding 等方法指定編碼:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

這樣就 ok 了:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

要注意,這種情況下,response header 中仍然沒有 charset 信息,所以要在 meta 中指定。

也可以用 setcontenttype (或前面一直用的 setheader,其實兩者是等價的):

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

也能達成同樣效果:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

這種情況下,response header 中包含 charset 信息,所以前面的代碼中可以省略在 meta 中的聲明:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

那么,現(xiàn)在我們明白了,printwriter 的缺省與普通字符流的缺省是不同的,機制有所差別。

使用普通字符流,缺省編碼

當然如果你一定要用普通字符流,也是可以的,但最后需要主動 flush:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

這時的缺省就是 charset.defaultcharset 中的值了,這里把它拼在了 meta 和最終的輸出中,響應也是正常的:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

結果是 utf-8。跟前面所說的 tomcat server 啟動時參數(shù)的值一致。

使用普通字符流,顯式指定編碼

如果不打算用缺省,那就直接指定:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

結果同樣是 ok 的:

Java servlet 使用 PrintWriter 時的編碼與亂碼的示例代碼

當然,一般還是建議使用 printwriter 來輸出,而即便你一定要用普通字符流,也最好不要用缺省。

那么關于 java servlet 中使用 printwriter 時的編碼與亂碼問題就介紹到這里。本文中的示例代碼見:servlet-printwriter.rar

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://xiaogd.net/java-servlet-使用-printwriter-時的編碼與亂碼/

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 三体动漫在线观看免费完整版2022 | 欧美xxoo做爰猛烈视频 | 69午夜影院 | 欧美久久久久久久一区二区三区 | 双性总裁(h) | 久9视频这里只有精品123 | 四虎免费在线观看 | 丰满艳妇亲伦视频 | 91九色麻豆 | 日本孕妇与黑人xxxxxx | 四虎1515hhh co m| 久久精品国产亚洲AV热无遮挡 | 高h短篇校园1v1 | 草莓丝瓜芭乐樱桃榴莲色多黄 | 日本成人黄色片 | 射西西| 欧美1区| 紧身牛仔裤美女被啪啪久久网 | 免费看麻豆视频 | www.福利| 喜马拉雅听书免费版 | 色婷婷婷婷 | 日本高清视频网站www | 国产美女做爰免费视频网址 | 高清一区高清二区视频 | 日韩精品视频福利资源站 | 91综合精品网站久久 | 成人福利在线观看 | 非洲黑人又大粗gay 非洲黑人bbwbbwbbw | 日本精a在线观看 | 免费久久久久 | 男人女人日皮视频 | 日本中年japanesebear | 女海盗斯蒂内塔的复仇2免费观看 | 久久久免费热线精品频 | 四虎影院的网址 | 亚洲成人在线播放 | 男人的天堂在线观看视频不卡 | 韩国甜性涩爱在线播放 | 国产精品一区二区久久 | 2019nv天堂香蕉在线观看 |