五一節回了老家一趟,于是就有了借口不更新自己的日志了,前幾天上來看到傳說一夢給我留了2條留言說用SVNWebClient上傳中文文件名的文件時,會出現亂碼。說老實話,當初推薦SVNWebClient和sventon時,也只當它們是純粹的基于Web的SVN瀏覽工具,所以也就沒有去測試這個中文上傳和中文注釋的問題。還好當初雖然不怎樣看好SVNWebClient,但也沒有將其卸載,于是就試了一把。好險,差一點就沒有測出來。傳說一夢也不說說清楚,是當文件名中出現奇數個中文的時候會出現亂碼,而偶數個時就OK,當然,我一開始試的就剛好是類似于"中文名.txt"子類的。于是殺到SVNWebClient的網站,在其論壇上看到已經有人提了問題了,只是沒人問津,這不明擺著欺負中國人嘛!NND,只有發揚開源精神,自己動手了,盡管我是不會用SVNWebClient做SVN客戶端工具的,放著那么好的TortoiseSVN不用,不是自己找難受嘛。
大體關于中文亂碼的問題,其實就是個編碼的問題,打開SVNWebClient的源碼,找到處理上傳的servlet:org.polarion.svnwebclient.util.Uploader.java,不是好好的嘛,用的是Jarkata的FileUpload,也做了utf8的轉碼,不應該有錯啊。在其轉換前后加了點調試代碼,發現沒有什么特別的東西。不過,聯想到以前用過的其它文件上傳組件,往往對中文的處理沒有考慮周全,正準備將其代碼也下載下來研究一把,突然發現其最新的版本是1.1,而SVNWebClient使用的是1.0,心想不要其已經自動糾正了。下載新的版本,不過新版本還需要Jarkata的IO庫,一并下載,然后按照其文檔,改用最新的ServletFileUpload,重新編譯部署。這次亂得可比較徹底了,不管偶數個還是奇數個中文都是亂碼,不過,好在在轉換前后加了點調試,發現文件名在沒有轉換前竟然是正常的,于是幾次嘗試后,終于將其搞定。Uploader.java最新代碼如下:

import ?org.apache.commons.fileupload.servlet.ServletFileUpload;
import ?org.apache.commons.fileupload.disk.DiskFileItemFactory;

public ? class ?Uploader?{
???? public ? static ?Map?doPost(HttpServletRequest?request,?HttpServletResponse?responce,?String?destinationDirectory,?String?tempDirectory)?{
????????Map?parameters? = ? new ?HashMap();
????????File?tempDir? = ? new ?File(tempDirectory);
???????? if ?( ! tempDir.exists())?{
????????????tempDir.mkdirs();
????????}
????????File?destDir? = ? new ?File(destinationDirectory);
???????? if ?( ! destDir.exists())?{
????????????destDir.mkdirs();
????????}
????????ServletFileUpload?fu? = ? new ?ServletFileUpload( new ?DiskFileItemFactory( 4096 ,? new ?java.io.File(tempDirectory)));
????????List?fileItems? = ? null ;
???????? try ?{
????????????fileItems? = ?fu.parseRequest(request);
????????}? catch ?(FileUploadException?e)?{
????????????Logger.getInstance(Uploader. class ).error(e,?e);
????????}
???????? for ?(Iterator?i? = ?fileItems.iterator();?i.hasNext();)?{
????????????FileItem?fi? = ?(FileItem)?i.next();
???????????? if ?(fi.isFormField())?{
???????????????? try ?{
????????????????????parameters.put(fi.getFieldName(),?fi.getString( " UTF8 " ));
????????????????}? catch ?(UnsupportedEncodingException?e)?{
????????????????????Logger.getInstance(Uploader. class ).error(e,?e);
????????????????}
????????????}? else ?{
???????????????? // ?filename?on?the?client
????????????????String?fileName? = ?fi.getName();
???????????????? // ?write?the?file
???????????????? try ?{
????????????????????File?uploadFile? = ? new ?File(destinationDirectory? + ? " / " ? + ?FileUtil.getLastPathElement(fileName));
????????????????????fi.write(uploadFile);
???????????????????? // ?fi.delete();
????????????????}? catch ?(Exception?e)?{
????????????????????Logger.getInstance(Uploader. class ).error(e,?e);
????????????????}
????????????????parameters.put(FormParameters.FILE_NAME,?FileUtil.getLastPathElement(fileName));
????????????}
????????}
???????? return ?parameters;
????}
}
另外,不懂或者不愿意去學Java的人就不要用SVNWebClient和sventon了,世界上有那么多的各種各樣語言編寫的開源工具,干嘛不選一個自己熟悉的呢^_^。
Uploader.java下載
Uploader.class下載