2007年9月10日星期一

关于用SVNWebClient提交中文文件名出错的问题

五一节回了老家一趟,于是就有了借口不更新自己的日志了,前几天上来看到传说一梦给 我留了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下载

没有评论: