diff --git a/disconf-web/html/mainTpl/newconfig_file.tpl.html b/disconf-web/html/mainTpl/newconfig_file.tpl.html index b27b4d40b..72018b592 100644 --- a/disconf-web/html/mainTpl/newconfig_file.tpl.html +++ b/disconf-web/html/mainTpl/newconfig_file.tpl.html @@ -95,7 +95,7 @@

新建配置文件

- 支持任意类型配置文件(.properties文件可支持自动注入,非.properties文件则只是简单托管) + 支持任意类型配置文件(.properties文件可支持自动注入,.zip文件可以自动搜索其中的properties文件列表,非.properties文件则只是简单托管)
diff --git a/disconf-web/html/newconfig_file.html b/disconf-web/html/newconfig_file.html index 3d0ab80a7..d4ba7418d 100644 --- a/disconf-web/html/newconfig_file.html +++ b/disconf-web/html/newconfig_file.html @@ -181,7 +181,7 @@

新建配置文件

- 支持任意类型配置文件(.properties文件可支持自动注入,非.properties文件则只是简单托管) + 支持任意类型配置文件(.properties文件可支持自动注入,.zip文件可以自动搜索其中的properties文件列表,非.properties文件则只是简单托管)
diff --git a/disconf-web/pom.xml b/disconf-web/pom.xml index c6628aab5..43a3ccf13 100644 --- a/disconf-web/pom.xml +++ b/disconf-web/pom.xml @@ -331,7 +331,12 @@ junit test - + + + org.apache.ant + ant + 1.9.4 + diff --git a/disconf-web/src/main/java/com/baidu/disconf/web/utils/ZipUtil.java b/disconf-web/src/main/java/com/baidu/disconf/web/utils/ZipUtil.java new file mode 100644 index 000000000..e0c935727 --- /dev/null +++ b/disconf-web/src/main/java/com/baidu/disconf/web/utils/ZipUtil.java @@ -0,0 +1,149 @@ +package com.baidu.disconf.web.utils; + +import org.apache.tools.zip.ZipEntry; +import org.apache.tools.zip.ZipFile; +import org.apache.tools.zip.ZipOutputStream; + +import java.io.*; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + + +/** + * 压缩或解压zip: + * 由于直接使用java.util.zip工具包下的类,会出现中文乱码问题,所以使用ant.jar中的org.apache.tools.zip下的工具类 + * @author jack_lcz + */ + +public class ZipUtil { + private static byte[] _byte = new byte[1024] ; + /** + * 压缩文件或路径 + * @param zip 压缩的目的地址 + * @param srcFiles 压缩的源文件 + */ + public static void zipFile( String zip , List srcFiles ){ + try { + if( zip.endsWith(".zip") || zip.endsWith(".ZIP") ){ + ZipOutputStream _zipOut = new ZipOutputStream(new FileOutputStream(new File(zip))) ; + _zipOut.setEncoding("GBK"); + for( File _f : srcFiles ){ + handlerFile(zip , _zipOut , _f , ""); + } + _zipOut.close(); + }else{ + System.out.println("target file[" + zip + "] is not .zip type file"); + } + } catch (FileNotFoundException e) { + } catch (IOException e) { + } + } + + /** + * + * @param zip 压缩的目的地址 + * @param zipOut + * @param srcFile 被压缩的文件信息 + * @param path 在zip中的相对路径 + * @throws IOException + */ + private static void handlerFile(String zip , ZipOutputStream zipOut , File srcFile , String path ) throws IOException{ + System.out.println(" begin to compression file[" + srcFile.getName() + "]"); + if( !"".equals(path) && ! path.endsWith(File.separator)){ + path += File.separator ; + } + if( ! srcFile.getPath().equals(zip) ){ + if( srcFile.isDirectory() ){ + File[] _files = srcFile.listFiles() ; + if( _files.length == 0 ){ + zipOut.putNextEntry(new ZipEntry( path + srcFile.getName() + File.separator)); + zipOut.closeEntry(); + }else{ + for( File _f : _files ){ + handlerFile( zip ,zipOut , _f , path + srcFile.getName() ); + } + } + }else{ + InputStream _in = new FileInputStream(srcFile) ; + zipOut.putNextEntry(new ZipEntry(path + srcFile.getName())); + int len = 0 ; + while( (len = _in.read(_byte)) > 0 ){ + zipOut.write(_byte, 0, len); + } + _in.close(); + zipOut.closeEntry(); + } + } + } + + /** + * 解压缩ZIP文件,将ZIP文件里的内容解压到targetDIR目录下 + */ + public static List upzipFile(String zipPath, String descDir) { + return upzipFile( new File(zipPath) , descDir ) ; + } + + /** + * 对.zip文件进行解压缩 + * @param zipFile 解压缩文件 + * @param descDir 压缩的目标地址,如:D:\\测试 或 /mnt/d/测试 + * @return + */ + @SuppressWarnings("rawtypes") + public static List upzipFile(File zipFile, String descDir) { + List _list = new ArrayList() ; + try { + ZipFile _zipFile = new ZipFile(zipFile , "GBK") ; + for( Enumeration entries = _zipFile.getEntries() ; entries.hasMoreElements() ; ){ + ZipEntry entry = (ZipEntry)entries.nextElement() ; + File _file = new File(descDir + File.separator + entry.getName()) ; + if( entry.isDirectory() ){ + _file.mkdirs() ; + }else{ + File _parent = _file.getParentFile() ; + if( !_parent.exists() ){ + _parent.mkdirs() ; + } + InputStream _in = _zipFile.getInputStream(entry); + OutputStream _out = new FileOutputStream(_file) ; + int len = 0 ; + while( (len = _in.read(_byte)) > 0){ + _out.write(_byte, 0, len); + } + _in.close(); + _out.flush(); + _out.close(); + _list.add(_file) ; + } + } + } catch (IOException e) { + } + return _list ; + } + + /** + * 对临时生成的文件夹和文件夹下的文件进行删除 + */ + public static void deletefile(String delpath) { + try { + File file = new File(delpath); + if (!file.isDirectory()) { + file.delete(); + } else if (file.isDirectory()) { + String[] filelist = file.list(); + for (int i = 0; i < filelist.length; i++) { + File delfile = new File(delpath + File.separator + filelist[i]); + if (!delfile.isDirectory()) { + delfile.delete(); + } else if (delfile.isDirectory()) { + deletefile(delpath + File.separator + filelist[i]); + } + } + file.delete(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/disconf-web/src/main/java/com/baidu/disconf/web/web/config/controller/ConfigNewController.java b/disconf-web/src/main/java/com/baidu/disconf/web/web/config/controller/ConfigNewController.java index f90bb6041..e9bb599df 100644 --- a/disconf-web/src/main/java/com/baidu/disconf/web/web/config/controller/ConfigNewController.java +++ b/disconf-web/src/main/java/com/baidu/disconf/web/web/config/controller/ConfigNewController.java @@ -3,6 +3,9 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; +import com.baidu.disconf.core.common.utils.FileUtils; +import com.baidu.disconf.web.utils.ZipUtil; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -24,6 +27,11 @@ import com.baidu.dsp.common.exception.FileUploadException; import com.baidu.dsp.common.vo.JsonObjectBase; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + /** * 专用于配置新建 * @@ -35,6 +43,7 @@ public class ConfigNewController extends BaseController { protected static final Logger LOG = LoggerFactory.getLogger(ConfigUpdateController.class); + private static final String TMP_FILE_PATH = "/tmp"; @Autowired private ConfigMgr configMgr; @@ -75,7 +84,7 @@ public JsonObjectBase newItem(@Valid ConfNewItemForm confNewForm) { */ @ResponseBody @RequestMapping(value = "/file", method = RequestMethod.POST) - public JsonObjectBase updateFile(@Valid ConfNewForm confNewForm, @RequestParam("myfilerar") MultipartFile file) { + public JsonObjectBase updateFile(@Valid ConfNewForm confNewForm, @RequestParam("myfilerar") MultipartFile file) throws IOException { LOG.info(confNewForm.toString()); @@ -83,36 +92,13 @@ public JsonObjectBase updateFile(@Valid ConfNewForm confNewForm, @RequestParam(" // 校验 // int fileSize = 1024 * 1024 * 4; - String[] allowExtName = {".properties", ".xml"}; + String[] allowExtName = {".properties", ".xml",".zip"}; fileUploadValidator.validateFile(file, fileSize, allowExtName); - // - // 更新 - // - String fileContent = ""; - try { - - fileContent = new String(file.getBytes(), "UTF-8"); - LOG.info("receive file: " + fileContent); - - } catch (Exception e) { + // 处理(新增压缩包) + String retMessage = handleAndSaveFileContent(confNewForm,file); - LOG.error(e.toString()); - throw new FileUploadException("upload file error", e); - } - - // 创建配置文件表格 - ConfNewItemForm confNewItemForm = new ConfNewItemForm(confNewForm); - confNewItemForm.setKey(file.getOriginalFilename()); - confNewItemForm.setValue(fileContent); - - // 业务校验 - configValidator.validateNew(confNewItemForm, DisConfigTypeEnum.FILE); - - // - configMgr.newConfig(confNewItemForm, DisConfigTypeEnum.FILE); - - return buildSuccess("创建成功"); + return buildSuccess(retMessage); } /** @@ -144,4 +130,62 @@ public JsonObjectBase updateFileWithText(@Valid ConfNewForm confNewForm, @NotNul return buildSuccess("创建成功"); } + + + /** + * 配置文件,统一处理方法 + */ + private String handleAndSaveFileContent(ConfNewForm confNewForm, MultipartFile file) throws IOException { + //step 1: 获取文件后缀信息 + String filename = file.getOriginalFilename(); + String extName = filename.substring(filename.lastIndexOf(".")).toLowerCase(); + + //step 2: 定义待处理的文件列表数据 + List configFiles = new ArrayList(); + + //step 3: 处理文件列表 + File tmpConfigFile = new File(TMP_FILE_PATH,file.getOriginalFilename()); + FileUtils.copyInputStreamToFile(file.getInputStream(), tmpConfigFile); + if(StringUtils.equals(extName,".properties")){ + configFiles.add(tmpConfigFile); + }else if(StringUtils.equals(extName,".zip")){ + configFiles = ZipUtil.upzipFile(tmpConfigFile,TMP_FILE_PATH); + }else{ + //Nothing + } + + //step 4: 保存文件信息 + saveFileContent(configFiles,confNewForm); + + return "处理成功"; + + } + + private void saveFileContent(List configFiles,ConfNewForm confNewForm){ + + for(File file : configFiles){ + String fileContent = ""; + try { + fileContent = new String(FileUtils.readFileToString(file,"UTF-8")); + LOG.info("receive file: " + fileContent); + + } catch (Exception e) { + LOG.error(e.toString()); + throw new FileUploadException("upload file error", e); + } + + + // 创建配置文件表格 + ConfNewItemForm confNewItemForm = new ConfNewItemForm(confNewForm); + confNewItemForm.setKey(file.getName()); + confNewItemForm.setValue(fileContent); + + // 业务校验 + configValidator.validateNew(confNewItemForm, DisConfigTypeEnum.FILE); + + // 目前都是没有事务支持的,@jack_lcz + configMgr.newConfig(confNewItemForm, DisConfigTypeEnum.FILE); + } + } + }