<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    HelloWorld 善戰(zhàn)者,求之于勢,不責(zé)于人;故能擇人而任勢。

    知止而后有定,定而后能靜,靜而后能安,安而后能慮,慮而后能得。物有本末,事有終始。知所先后,則近道矣。

      BlogJava :: 首頁 ::  :: 聯(lián)系 ::  :: 管理 ::
      167 隨筆 :: 1 文章 :: 40 評論 :: 0 Trackbacks
    Unicode網(wǎng)頁中上傳下載文件時發(fā)生文件名亂碼的問題
       String   filename="測試";
       String client = request.getHeader("user-agent").toLowerCase();
       if (client.indexOf("msie") >= 0) {
        filename = java.net.URLEncoder.encode(filename, "utf-8");
       } else {
        filename = javax.mail.internet.MimeUtility.encodeText(filename,"utf-8","B");
       }
       response.setContentType("APPLICATION/OCTET-STREAM");
       response.addHeader("Content-Disposition", "attachment; filename="+filename+".exe");
       OutputStream os = response.getOutputStream();
       File f = new File ("C:/Downloads/core JavaServer™ Faces.chm");
       FileInputStream isf = new FileInputStream(f);
       InputStreamReader isr = new InputStreamReader(isf);
       BufferedReader rb = new BufferedReader(isr);
       byte[] b = new byte[10240];
       int i = 0;
       while (isf.read(b) != -1) {
        os.write(b);
       }
       os.close();
    通過此頁面進(jìn)行文件上傳后, IE, NC以及FF所傳輸?shù)臄?shù)據(jù)均相同. 如下

    Content-Type: multipart/form-data; boundary=---------------------------282302224217945
    Content-Length: 27980

    -----------------------------282302224217945
    Content-Dis;form-data; name="theText"

    C:\縺ゅ≠縺ゅ≠.xls
    -----------------------------282302224217945
    Content-Dis;form-data; name="theFile"; filename="縺ゅ≠縺ゅ≠.xls"
    Content-Type: application/vnd.ms-excel

    可以看出, 對text box和file upload box中的文件名所有瀏覽器均采取了相同的編碼. 經(jīng)證實, 是上傳頁面的編碼方式——所有瀏覽器均對unicode數(shù)據(jù)(utf-8)采取了本地的編碼方式(這里是ms932).

    在服務(wù)器端對上傳的數(shù)據(jù)進(jìn)行解碼.

    解碼的方式有很多, 這里我使用最普遍以及正規(guī)的request.setCharacterEncoding的方法. 發(fā)現(xiàn)form表單中的text box可以被正常解碼, 但是file upload box中的文件名無法通過這種方式解碼. 所以只能使用手工解碼.

    String fixedFileName = new String(fileName.getBytes("SJIS"), "UTF-8");

    其中SJIS是客戶端系統(tǒng)的編碼, UTF-8是客戶端頁面的編碼.

    上傳文件測試中, 所有瀏覽器表現(xiàn)一致, 需要注意的是文件名和表單數(shù)據(jù)的不同處理方式.

    下載文件

    使用一個unicode的JSP頁面, 在頁面上有一個固定的超鏈接, 傳遞給服務(wù)器一個文件名. 服務(wù)器依照這個文件名把服務(wù)器端的文件傳遞給客戶端.

    下載頁面

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">

    <a href="download.do?name=ああああ.xls">ダウンロード</a>

    對于這樣一個頁面, 當(dāng)點擊超鏈接后, 各瀏覽器處理方式不同

    IE會把超鏈接依照頁面當(dāng)前編碼方式編碼(這里是utf-8)后, 發(fā)送給服務(wù)器端

    GET /nsupload/download.do?name=縺ゅ≠縺ゅ≠.xls HTTP/1.1

    NC和FF會把超鏈接依照頁面編碼方式編碼(這里是utf-8)后, 再通過url encoding后, 發(fā)送給服務(wù)器端

    GET /nsupload/download.do?name=%E3%81%82%E3%81%82%E3%81%82%E3%81%82.xls HTTP/1.1

    (經(jīng)證實, E38182是「あ」的unicode代碼)

    在服務(wù)器收到提交的數(shù)據(jù)后, 需要對其進(jìn)行解碼. 需要注意的是這種方式下使用request.setCharacterEncoding無效. 所以必須手工解碼.

    name = new String(name.getBytes("ISO-8859-1"), "UTF-8");

    其中ISO-8859-1是Tomcat服務(wù)器的特性, Tomcat會把所有的數(shù)據(jù)先轉(zhuǎn)換為ISO-8859-1的形式. UTF-8是實際的編碼方式.

    在得到文件名后, 就可以正確地讀取文件, 然后把文件傳遞給客戶端了. 其中, 文件名是保存在Http報頭(header)的Content-Disposition中.

    response.setHeader("Content-Disposition", "inline; filename=" + _filename);
    //或者
    response.setHeader("Content-Disposition", "attachment; filename=" + _filename);

    經(jīng)實驗證明, 使用inline或者attachment對文件名的編碼方式沒有影響.

    另外一個需要設(shè)置的是Content-Type.

    response.setContentType("application/vnd.ms-excel");
    //或者
    response.setContentType("application/vnd.ms-excel; charset=UTF-8");
    //或者
    response.setContentType("application/x-download; >" + _filename);

    經(jīng)試驗證明, 使用application/*的任何形式都對文件名的編碼方式沒有影響.
    第二點, 經(jīng)試驗證明, 這里的charset設(shè)置會被三種瀏覽器忽略, 所以設(shè)置與否影響文件名的編碼方式.
    第三點, 經(jīng)試驗證明, 這里的name設(shè)置對文件名沒有任何影響.

    可能還有一個屬性需要注意, 就是Content-Language. 經(jīng)試驗證明, Content-Language有無, 或者為何值, 對文件名沒有任何影響.

    那么對于non-ascii的文件名如何操作才可以保證客戶端可以得到正確的顯示呢?

    經(jīng)過調(diào)查, 有三種方法(在網(wǎng)上搜索后認(rèn)為可能這篇文章是對于這個問題探討最深入的文章)

    第一, 使用URLEncoding方法. 即對文件名進(jìn)行URLEncoding.

    name = URLEncoder.encode(name, "UTF-8");


    這種方式適用于IE, 但是不適用于NC和FF. 在這種方式下, 網(wǎng)絡(luò)上傳輸?shù)氖莡rl encoding后的ascii編碼.

    Content-Dis;inline; filename=%E3%81%82%E3%81%82%E3%81%82%E3%81%82.xls

    NC和FF不能對這樣的文件名進(jìn)行有效的解碼
    第二, 使用字符串字符集強(qiáng)行轉(zhuǎn)換為本地字符集方法, 這樣做的原理是JVM底層全部為unicode. 所以一旦一個字符串表示了正確的字符集而被存儲后, 這個字符串會被轉(zhuǎn)換為任意字符集.

    原理二是, IE和FF對非url encoding的non-ascii文件名采用客戶端系統(tǒng)本地的編碼方式進(jìn)行轉(zhuǎn)換.

    name = new String(name.getBytes("Shift_JIS"), "ISO-8859-1");

    需要注意的是, 這里的name原本是utf-8的.

    在網(wǎng)絡(luò)上傳輸?shù)臑?br>
    Content-Dis;inline; filename=ああああ.xls


    經(jīng)過試驗, IE和FF支持這種方式, NC不支持. 表現(xiàn)為NC無法解析文件名.

    第三種, 使用Base64編碼文件名. 原理是這種做法符合RFC2047的定義.

    name = javax.mail.internet.MimeUtility.encodeText(name, "UTF-8", "B");

    使用到了JavaMail中的Base64編碼的類MimeUtility.

    在網(wǎng)絡(luò)上傳輸?shù)臑榻?jīng)過Base64編碼的ascii字符.

    Content-Dis;inline; filename==?UTF-8?B?44GC44GC44GC44GCLnhscw==?=

    只有FF支持這種方式, IE表現(xiàn)為無法解析文件名, NC表現(xiàn)為忽略Base64編碼.
    以上三種方法是目前來講, 使瀏覽器可以正確下載non-ascii文件名的方法. 其中IE支持兩種(url encoding和force transform), FF支持兩種(force transform和base64 encoding), NC一種都不支持.

    關(guān)于這次調(diào)查的結(jié)果, 對于NC多說兩句, 我以為這個結(jié)果是由于NC 7.1和Tomcat 5.5不兼容造成的. Tomcat 5.5要求必須把所有報頭先轉(zhuǎn)變?yōu)镮SO-8859-1的格式, 而NC 7.1卻無法直接對ISO-8859-1進(jìn)行正確的解析或者說是解析功能比較弱. 如果有時間, 我會繼續(xù)驗證非unicode的情況以及NC 8的情況.


    ---2006年9月14日21:00 補(bǔ)充---

    在NC 8.1上進(jìn)行了測試, 測試結(jié)果是NC 8.1支持方法三, 即base64 encoding.

    </script>

    posted on 2007-08-13 18:53 helloworld2008 閱讀(535) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 永久黄色免费网站| 国产成人免费ā片在线观看老同学| 亚洲国产最大av| 国产精品亚洲精品| 99视频全部免费精品全部四虎| 女人18毛片a级毛片免费| 国产成人无码区免费A∨视频网站 国产成人涩涩涩视频在线观看免费 | 亚洲色偷精品一区二区三区| 亚洲高清毛片一区二区| 亚洲一级片免费看| 24小时日本电影免费看| 亚洲无圣光一区二区| 猫咪www免费人成网站| 99久在线国内在线播放免费观看 | 亚洲精华液一二三产区| 暖暖在线日本免费中文| 亚洲国产精品久久久久久| 亚洲一日韩欧美中文字幕在线| AA免费观看的1000部电影| 亚洲中文字幕无码不卡电影 | 日本亚洲欧洲免费天堂午夜看片女人员| 91午夜精品亚洲一区二区三区| 久香草视频在线观看免费| 免费无码A片一区二三区| 亚洲成色www久久网站夜月| 日韩插啊免费视频在线观看| 亚洲二区在线视频| 国产成人一区二区三区免费视频| 日韩在线视频播放免费视频完整版| 一个人在线观看视频免费| 亚洲精品成a人在线观看夫 | 女人18毛片特级一级免费视频| 国产精品亚洲综合网站| 99re热免费精品视频观看| 国产精品成人亚洲| 亚洲成a人片在线观看中文动漫| 国产乱子伦精品免费视频| 免费国产小视频在线观看| 在线a亚洲老鸭窝天堂av高清| 四虎影在线永久免费四虎地址8848aa | 亚洲精品在线播放视频|