標籤文件下載文件名亂碼問題

近期項目中用到了extjs的上傳控件上傳文件,而後頁面使用a標籤直接調用後臺action獲取流進行下載。在本地tomcat下是沒有什麼問題的,可是當放到測試環境jboss下的時候卻遇到了文件名亂碼的問題。如下爲關鍵代碼:javascript

<!-- 附件下載 -->
        <action name="downloadFile"
            class="com.deppon.cc.module.kminfo.server.action.KmInfoAction"
            method="downloadFile">
            <result name="success" type="stream">
                 <param name="contentType">application/octet-stream</param>
                 <param name="inputName">fileStream</param>
                 <param name="contentDisposition">  
                        attachment;filename="${fileUpdateFileName}"  
                 </param>  
            </result>
        </action>
public InputStream getInputStream(String id){
        if ("".equals(id) || id == null) {
            log.warn("id is null");
            throw new FileStorageException(FileStorageException.COMMON_FILE_IDISBLANK);
        }
        FileEntity res = fileStorageDao.get(id);
        if(res == null) {
            log.warn("get file is null");
            throw new FileStorageException(FileStorageException.COMMON_FILE_GETFILEISBLANK);
        }
        byte[] sfile = res.getSerializedFile();
        //根據ID獲取文件
        InputStream fis = new ByteArrayInputStream(sfile);
        return fis;
    }
/*頁面中用<a>標籤進行下載*/
var url = "../kminfo/downloadFile.action?kmInfoVO.fileUpdateId=" + annex + "&&kmInfoVO.fileUpdateFileName=" + annexName;
var uploadAttachmentForm = infoEditWindow.down('form').down('form').getForm().findField('fileUpdateNameDisp').setValue("<a href ='"+ url +"'>"+annexName+"</a>");

當點擊a標籤以後,文件名稱和文件id會被傳到後臺,後臺根據文件id去查找文件,而後放入流中,struts2中的配置了下載的文件名,它會去調用getFileUpdateFileName()方法去取的文件名,而後再返回到前臺。
由於是經過a標籤傳的中文,在到達後臺的時候已經被解碼成了不知道什麼編碼,試着在後臺get方法中對文件進行轉換:java

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

本地可行,可是jboss下仍是亂碼。試了不少的方法都沒辦法解決這個問題,最後決定在前臺就對中文名進行轉碼,而後到後臺去解碼。瀏覽器

/*頁面中用<a>標籤進行下載*/
var url = "../kminfo/downloadFile.action?kmInfoVO.fileUpdateId=" + annex + "&&kmInfoVO.fileUpdateFileName=" + encodeURI(encodeURI(annexName));
var uploadAttachmentForm = infoEditWindow.down('form').down('form').getForm().findField('fileUpdateNameDisp').setValue("<a href ='"+ url +"'>"+annexName+"</a>");

這裏必需要encodeURI兩次,若是是一次的話瀏覽器仍是會把他解析爲中文,那麼也就無效了。tomcat

public String downloadFile(){
        try {
            getKmInfoVO().setFileUpdateFileName(new String(URLDecoder.decode(getKmInfoVO().getFileUpdateFileName(),"UTF-8").getBytes("UTF-8"),
                    "ISO-8859-1"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        InputStream fileStream = fileStorageService.getInputStream(getKmInfoVO().getFileUpdateId());
        kmInfoVO.setFileStream(fileStream);
        return SUCCESS;
    }

後臺只須要URLDecoder一次就能夠成功解碼了,最後通過在本地和測試環境上均可行。最後再說一下,不少狀況下,咱們在寫程序的時候都會把代碼設置爲UTF-8的編碼,能夠在下載文件設置filename的時候卻要設置編碼格式爲ISO-8859-1(如是英文的話就不須要這樣處理了)。
先說爲何使用 ISO-8859-1 編碼,這個主要是因爲http協議,http header頭要求其內容必須爲iso-8859-1編碼,因此咱們最終要把其編碼爲 ISO-8859-1 編碼的字符串;
可是前面爲何不直接使用 "中文文件名".getBytes("ISO-8859-1"); 這樣的代碼呢?由於ISO-8859-1編碼的編碼表中,根本就沒有包含漢字字符,固然也就沒法經過"中文文件名".getBytes("ISO-8859-1");來獲得正確的「中文文件名」在ISO-8859-1中的編碼值了,因此再經過new String()來還原就無從談起了。 因此先經過 "中文文件名".getBytes("utf-8") 獲取其 byte[] 字節,讓其按照字節來編碼,即在使用 new String("中文文件名".getBytes("utf-8"), "ISO-8859-1") 將其從新組成一個字符串,傳送給瀏覽器。app

相關文章
相關標籤/搜索