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


近期項目中用到了extjs的上傳控件上傳文件,然后頁面使用a標簽直接調用后台action獲取流進行下載。在本地tomcat下是沒有什么問題的,但是當放到測試環境jboss下的時候卻遇到了文件名亂碼的問題。以下為關鍵代碼:

<!-- 附件下載 -->
		<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方法中對文件進行轉換:

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兩次,如果是一次的話瀏覽器還是會把他解析為中文,那么也就無效了。

	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") 將其重新組成一個字符串,傳送給瀏覽器。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM