今天做一小項(xiàng)目,需求是這樣:
從本地上傳文件,歸檔到一個(gè)指定的目錄,然后將該目錄下的文件上傳至ftp服務(wù)器。并且可以從本地文件系統(tǒng),ftp服務(wù)器上下載特定的資源。
如下:
業(yè)務(wù)邏輯不難,但是處理中文亂碼比較棘手,經(jīng)過徹夜努力,終于解決掉
處理思路:
由于項(xiàng)目使用Struts2,因此,項(xiàng)目編碼設(shè)置為UTF-8。
開發(fā)是在win系統(tǒng)下的,如果移植到linux平臺(tái),在文件上傳下載時(shí),必然會(huì)出現(xiàn)中文亂碼。
我的解決辦法:
指定兩個(gè)參數(shù):
serverEncode = gbk; // 服務(wù)器編碼
projectEncode = utf-8 // 項(xiàng)目編碼
// 聲明轉(zhuǎn)碼方法
getISOToServerEncode(Object obj);//iso8859-1 -> 服務(wù)器編碼
getISOToProjectEncode(Object obj);//iso8859-1 -> 項(xiàng)目編碼
getServerEncodeToISO(Object obj);//iso8859-1 <- 服務(wù)器編碼
getProjectEncodeToISO(Object obj);//iso8859-1 <- 項(xiàng)目編碼
指定好之后,要分清兩種情況:
1. 前臺(tái)通過form表單提交的數(shù)據(jù)(post提交),在action層不需要處理,直接能正常顯示;
2.前臺(tái)通過超鏈接,url參數(shù)提交等(即為get方式提交)時(shí),在action層一定要進(jìn)行轉(zhuǎn)碼。
對(duì)get提交的轉(zhuǎn)碼分兩種情況:
1.提交的參數(shù)不參與本地文件系統(tǒng)的操作,那么轉(zhuǎn)成項(xiàng)目編碼。
2.提交的參數(shù)參與本地文件系統(tǒng)操作,即:提供文件上傳,下載等,必須轉(zhuǎn)換成服務(wù)器編碼;
OK,分清了上述情況之后,亂碼問題基本解決。
在下載部分,一般我們使用如下設(shè)置:
<action name="download" class="browserDocumentAction" method="download">
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">filename="${name}"</param>
</result>
<result name="input">err.jsp</result>
</action>
這里尤其要注意,getInputStream()方法的返回值不能為空,為空時(shí),會(huì)把a(bǔ)ction文件下載下來,不是我們想要的內(nèi)容。
另外,通過filename獲得下載的文件名時(shí),在download()方法里面一定要把name從項(xiàng)目編碼轉(zhuǎn)換為iso8859-1編碼,這樣才能正確顯示下載時(shí)的文件名。
以上是下載部分的說明,上傳不需要進(jìn)行任何的轉(zhuǎn)碼(項(xiàng)目為utf8時(shí))。
在ftp操作部分,由于是對(duì)文件系統(tǒng)進(jìn)行的操作,因此在整個(gè)交換過程中,必須把所有的編碼都制定為服務(wù)器編碼。
即:將請(qǐng)求路徑設(shè)置為:serverEncode -> iso859-1;獲取到文件列表后,再做逆向轉(zhuǎn)碼。
另外,部分ftp軟件錯(cuò)誤提示不太一樣,但對(duì)ftp的操作,大概有以下可能:
1. 中文路徑創(chuàng)建錯(cuò)誤(在ftpClient中必須使用iso8859-1編碼);
2.保存文件錯(cuò)誤(必須能正確獲取本地文件流,且將保存到ftp的文件名轉(zhuǎn)碼為iso8859-1后再做操作);