缘起
公司每位员工都有一些重要的文档需要备份,或共享给其他人。备份是安全的需要(防止资料丢失),共享是沟通或版本一致性控制的需要,比如张三已经升级了某个程序的版本,李四却不知道,没有一个统一的文档控制出口。
探索
程序猿都习惯使用git服务实现版本管控,但add,commit,pull,push一顿操作,不管是命令模式,还是图像化模式,都让非专业人员一脸蒙圈。
于是探索文档管理系统,当然是找开源方案。对比了logicalDo和OpenKM,前者功能不满足,似乎性能也存在问题。最后选择了OpenKM-ce。
测试
测试功能的最好方式,是利用docker平台,非常顺利,启动即可用。因为需要批量上传文档,所以需要使用.zip文件上传在线解压功能,于是发现了中文目录和文件名,上传解压后出现乱码。
解决之路
当然是下载源码,github或者其他开源网站都可以找到。
mvn repository 的setting.xml使用ali的镜像即可。
依赖包下载如果不能一次成功,就多试几次。这个过程也比较折腾,最好的结论是,不需要翻墙,不需要怀疑包太老无法找到。
总之最后可以打包成功的。
运行环境准备
我是把docker容器里面的tomcat里面的设置文件拷贝到本地运行环境。但一直无法直接在idea里面直接运行,只能在终端把编译好的war包拷贝到tomcat/webapps下。调试只能利用日志文件,还行,就是效率偏低。
解决乱码问题
修改文件:com.openkm.servlet.frontend : FileUploadServlet.java
首先添加判断编码的函数
/**
* gaobaishuang 判断zip文件的编码格式(试错法)
* 此前采用直接对zipFile设置编码测试的方法,遇到的问题是一旦设置了一个错误的编码,就无法修正了。
* 这个方法是基于文件创建临时数据流,不怕是错,不伤及主程序的zipFile数据流。
* @param filepath
* @param charset
* @return
* @throws FileNotFoundException
*/
private boolean testEncoding(String filepath, Charset charset) throws FileNotFoundException {
FileInputStream fis = new FileInputStream(new File(filepath));
BufferedInputStream bis = new BufferedInputStream(fis);
ZipInputStream zis = new ZipInputStream(bis, charset);
ZipEntry zn = null;
try {
while ((zn = zis.getNextEntry()) != null) {
// do nothing
}
} catch (Exception e) {
return false;
}finally {
try {
zis.close();
bis.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
修改函数:importZip(String path, InputStream is),增加了“判断编码并设置”(见注释)
/**
* Import zipped documents
*
* @param path Where import into the repository.
* @param is The zip file to import.
*/
private synchronized String importZip(String path, InputStream is) throws PathNotFoundException, ItemExistsException,
AccessDeniedException, RepositoryException, IOException, DatabaseException, ExtensionException, AutomationException {
log.debug("importZip({}, {})", path, is);
java.io.File tmpIn = null;
java.io.File tmpOut = null;
String errorMsg = null;
try {
// Create temporal
tmpIn = File.createTempFile("okm", ".zip");
tmpOut = FileUtils.createTempDir();
FileOutputStream fos = new FileOutputStream(tmpIn);
IOUtils.copy(is, fos);
fos.close();
// Unzip files
ZipFile zipFile = new ZipFile(tmpIn);
//判断编码并设置
if (testEncoding(tmpIn.getPath(), Charset.forName("UTF-8")) == false){
zipFile.setFileNameCharset("GBK");
}
else
{
zipFile.setFileNameCharset("UTF-8");
}
zipFile.extractAll(tmpOut.getPath());
// Import files
StringWriter out = new StringWriter();
ImpExpStats stats = RepositoryImporter.importDocuments(null, tmpOut, path, false, false, false, out, new TextInfoDecorator(tmpOut));
if (!stats.isOk()) {
errorMsg = out.toString();
}
out.close();
} catch (ZipException e) {
log.error("Error importing zip", e);
throw new IOException(e.getMessage(), e);
} catch (IOException e) {
log.error("Error importing zip", e);
throw e;
} finally {
IOUtils.closeQuietly(is);
if (tmpIn != null) {
org.apache.commons.io.FileUtils.deleteQuietly(tmpIn);
}
if (tmpOut != null) {
org.apache.commons.io.FileUtils.deleteQuietly(tmpOut);
}
}
log.debug("importZip: {}", errorMsg);
return errorMsg;
}
至此,困扰了3天的编码问题得以解决,博客以记之。