diff --git a/datagear-connection/src/main/java/org/datagear/connection/IOUtil.java b/datagear-connection/src/main/java/org/datagear/connection/IOUtil.java index c6b88a3a..cdca2566 100644 --- a/datagear-connection/src/main/java/org/datagear/connection/IOUtil.java +++ b/datagear-connection/src/main/java/org/datagear/connection/IOUtil.java @@ -187,6 +187,7 @@ public class IOUtil * @param out * @param file * @param zipEntryName + * 文件的ZIP条目名,可以为{@code null}或者空字符串。 * @throws IOException */ public static void writeFileToZipOutputStream(ZipOutputStream out, File file, String zipEntryName) @@ -196,13 +197,26 @@ public class IOUtil return; boolean isDirectory = file.isDirectory(); + boolean isZipEntryNameEmpty = (zipEntryName == null || zipEntryName.isEmpty()); - if (isDirectory && !zipEntryName.endsWith("/")) - zipEntryName = zipEntryName + "/"; + if (isDirectory) + { + if (isZipEntryNameEmpty) + zipEntryName = ""; + else if (!zipEntryName.endsWith("/")) + zipEntryName = zipEntryName + "/"; + } + else if (isZipEntryNameEmpty) + { + zipEntryName = file.getName(); + isZipEntryNameEmpty = false; + } - ZipEntry zipEntry = new ZipEntry(zipEntryName); - - out.putNextEntry(zipEntry); + if (!isZipEntryNameEmpty) + { + ZipEntry zipEntry = new ZipEntry(zipEntryName); + out.putNextEntry(zipEntry); + } if (!isDirectory) { @@ -219,7 +233,8 @@ public class IOUtil } } - out.closeEntry(); + if (!isZipEntryNameEmpty) + out.closeEntry(); if (isDirectory) { diff --git a/datagear-web/src/main/java/org/datagear/web/cometd/dataexchange/CometdDataExchangeListener.java b/datagear-web/src/main/java/org/datagear/web/cometd/dataexchange/CometdDataExchangeListener.java index 57e63e0e..d0a0f259 100644 --- a/datagear-web/src/main/java/org/datagear/web/cometd/dataexchange/CometdDataExchangeListener.java +++ b/datagear-web/src/main/java/org/datagear/web/cometd/dataexchange/CometdDataExchangeListener.java @@ -193,11 +193,23 @@ public abstract class CometdDataExchangeListener implements DataExchangeListener message = getI18nMessage(code, e1.getSqlType()); } else - message = getI18nMessage(code); + { + message = getI18nMessage(code, getRootCauseMessage(e)); + } return message; } + protected String getRootCauseMessage(Throwable t) + { + Throwable cause = null; + + while ((cause = t.getCause()) != null) + t = cause; + + return t.getMessage(); + } + /** * 构建数据交换异常I18N消息码。 * diff --git a/datagear-web/src/main/java/org/datagear/web/cometd/dataexchange/CometdSubTextDataExportListener.java b/datagear-web/src/main/java/org/datagear/web/cometd/dataexchange/CometdSubTextDataExportListener.java index 22cb4770..ddb942fb 100644 --- a/datagear-web/src/main/java/org/datagear/web/cometd/dataexchange/CometdSubTextDataExportListener.java +++ b/datagear-web/src/main/java/org/datagear/web/cometd/dataexchange/CometdSubTextDataExportListener.java @@ -56,8 +56,10 @@ public class CometdSubTextDataExportListener extends CometdSubDataExchangeListen @Override protected DataExchangeMessage buildExceptionMessage(DataExchangeException e) { + int successCount = this._successCount.intValue(); + return new SubExceptionWithCount(getSubDataExchangeId(), resolveDataExchangeExceptionI18n(e), evalDuration(), - ExceptionResolve.ABORT, this._successCount.intValue(), 1); + ExceptionResolve.ABORT, successCount, (successCount > 0 ? 1 : 0)); } @Override diff --git a/datagear-web/src/main/java/org/datagear/web/controller/DataExchangeController.java b/datagear-web/src/main/java/org/datagear/web/controller/DataExchangeController.java index e2b17b7a..974e572a 100644 --- a/datagear-web/src/main/java/org/datagear/web/controller/DataExchangeController.java +++ b/datagear-web/src/main/java/org/datagear/web/controller/DataExchangeController.java @@ -18,6 +18,7 @@ import java.io.Writer; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -25,6 +26,7 @@ import java.util.Set; import java.util.concurrent.Future; import java.util.regex.Pattern; import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -282,7 +284,7 @@ public class DataExchangeController extends AbstractSchemaConnController return fileInfos; } - @RequestMapping(value = "/{schemaId}/import/csv/doImport") + @RequestMapping(value = "/{schemaId}/import/csv/doImport", produces = CONTENT_TYPE_JSON) @ResponseBody public ResponseEntity doImportCsv(HttpServletRequest request, HttpServletResponse response, @PathVariable("schemaId") String schemaId, @RequestParam("dataExchangeId") String dataExchangeId, @@ -364,8 +366,7 @@ public class DataExchangeController extends AbstractSchemaConnController public String viewLog(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model springModel, @PathVariable("schemaId") String schemaId, @RequestParam("dataExchangeId") String dataExchangeId, - @RequestParam("subDataExchangeId") String subDataExchangeId, - @RequestParam("subDataExchangeDisplayName") String subDataExchangeDisplayName) throws Throwable + @RequestParam("subDataExchangeId") String subDataExchangeId) throws Throwable { new VoidSchemaConnExecutor(request, response, springModel, schemaId, true) { @@ -378,7 +379,6 @@ public class DataExchangeController extends AbstractSchemaConnController springModel.addAttribute("dataExchangeId", dataExchangeId); springModel.addAttribute("subDataExchangeId", subDataExchangeId); - springModel.addAttribute("subDataExchangeDisplayName", subDataExchangeDisplayName); return "/dataexchange/view_log"; } @@ -466,7 +466,7 @@ public class DataExchangeController extends AbstractSchemaConnController return "/dataexchange/export_csv"; } - @RequestMapping(value = "/{schemaId}/export/csv/doExport") + @RequestMapping(value = "/{schemaId}/export/csv/doExport", produces = CONTENT_TYPE_JSON) @ResponseBody public ResponseEntity doExportCsv(HttpServletRequest request, HttpServletResponse response, @PathVariable("schemaId") String schemaId, @RequestParam("dataExchangeId") String dataExchangeId, @@ -491,9 +491,6 @@ public class DataExchangeController extends AbstractSchemaConnController List> writerFactories = toWriterResourceFactories(directory, exportForm.getFileEncoding(), fileNames); - List exportFileNames = new ArrayList(fileNames.length); - Collections.addAll(exportFileNames, fileNames); - Schema schema = getSchemaNotNull(request, response, schemaId); ConnectionFactory connectionFactory = new DataSourceConnectionFactory(new SchemaDataSource(schema)); @@ -532,7 +529,74 @@ public class DataExchangeController extends AbstractSchemaConnController dataExchangeId, batchDataExchange, subDataExchangeIds); storeBatchDataExchangeFutureInfo(request, futureInfo); - return buildOperationMessageSuccessEmptyResponseEntity(); + ResponseEntity responseEntity = buildOperationMessageSuccessEmptyResponseEntity(); + + Map subDataExchangeFileNameMap = buildSubDataExchangeFileNameMap(subDataExchangeIds, fileNames); + responseEntity.getBody().setData(subDataExchangeFileNameMap); + + return responseEntity; + } + + @RequestMapping(value = "/{schemaId}/export/download") + @ResponseBody + public void exptDownload(HttpServletRequest request, HttpServletResponse response, + @PathVariable("schemaId") String schemaId, @RequestParam("dataExchangeId") String dataExchangeId, + @RequestParam("fileName") String fileName) throws Exception + { + response.setCharacterEncoding(RESPONSE_ENCODING); + response.setHeader("Content-Disposition", + "attachment; filename=" + new String(fileName.getBytes(RESPONSE_ENCODING), "iso-8859-1") + ""); + + File directory = getTempDataExchangeDirectory(dataExchangeId, true); + File file = new File(directory, fileName); + + OutputStream out = null; + + try + { + out = response.getOutputStream(); + IOUtil.write(file, out); + } + finally + { + IOUtil.close(out); + } + } + + @RequestMapping(value = "/{schemaId}/export/downloadAll") + @ResponseBody + public void exptDownloadAll(HttpServletRequest request, HttpServletResponse response, + @PathVariable("schemaId") String schemaId, @RequestParam("dataExchangeId") String dataExchangeId) + throws Exception + { + String fileName = "export_csv.zip"; + + response.setCharacterEncoding(RESPONSE_ENCODING); + response.setHeader("Content-Disposition", + "attachment; filename=" + new String(fileName.getBytes(RESPONSE_ENCODING), "iso-8859-1") + ""); + + File directory = getTempDataExchangeDirectory(dataExchangeId, true); + + ZipOutputStream out = null; + try + { + out = new ZipOutputStream(response.getOutputStream()); + IOUtil.writeFileToZipOutputStream(out, directory, null); + } + finally + { + IOUtil.close(out); + } + } + + protected Map buildSubDataExchangeFileNameMap(String[] subDataExchangeIds, String[] fileNames) + { + Map map = new HashMap(); + + for (int i = 0; i < subDataExchangeIds.length; i++) + map.put(subDataExchangeIds[i], fileNames[i]); + + return map; } protected List toQueries(String[] queries) @@ -816,6 +880,12 @@ public class DataExchangeController extends AbstractSchemaConnController return logFile; } + protected File getExportFileZip(String dataExchangeId) + { + File file = new File(this.tempDataExchangeRootDirectory, dataExchangeId + ".zip"); + return file; + } + /** * 获取指定数据交换操作ID对应的cometd通道ID。 * diff --git a/datagear-web/src/main/resources/locales/datagear.properties b/datagear-web/src/main/resources/locales/datagear.properties index befef713..379cb524 100644 --- a/datagear-web/src/main/resources/locales/datagear.properties +++ b/datagear-web/src/main/resources/locales/datagear.properties @@ -58,6 +58,8 @@ restore=\u6062\u590D restoreAll=\u6062\u590D\u5168\u90E8 execute=\u6267\u884C rowNumber=\u884C\u53F7 +download=\u4E0B\u8F7D +downloadAll=\u4E0B\u8F7D\u5168\u90E8 dataTables.noData=\u6CA1\u6709\u6570\u636E dataTables.zeroRecords=\u6CA1\u6709\u7ED3\u679C @@ -432,9 +434,8 @@ dataExchange.exchangeStatus.SubExceptionWithCount.IGNORE=\u5FFD\u7565\uFF08{0}/{ dataExchange.exchangeStatus.SubExceptionWithCount.ROLLBACK=\u56DE\u6EDA\uFF08{0}/{1}\uFF0C{2}\uFF09 dataExchange.exchangeStatus.SubExchangingWithCount=\u8FDB\u884C\u4E2D\uFF08{0}/{1}\uFF09 dataExchange.exchangeStatus.SubSuccessWithCount=\u5B8C\u6210\uFF08{0}/{1}\uFF0C{2}\uFF09 -dataExchange.viewLog=\u67E5\u770B\u8BE6\u7EC6\u65E5\u5FD7\uFF1A{0} +dataExchange.viewLog=\u67E5\u770B\u8BE6\u7EC6\u65E5\u5FD7 dataExchange.cancelDeniedWithReason=\u53EA\u6709\u7B49\u5F85\u4E2D\u7684\u624D\u53EF\u4EE5\u53D6\u6D88 -dataexchange.viewDataExchangeLog=\u67E5\u770B\u6570\u636E\u4EA4\u6362\u65E5\u5FD7\uFF1A{0} dataExchange.error.ColumnNotFoundException=\u8868\u201C{0}\u201D\u4E2D\u6CA1\u6709\u201C{1}\u201D\u5217 dataExchange.error.TableMismatchException=\u8868\u201C{0}\u201D\u4E2D\u6CA1\u6709\u4EFB\u4F55\u5339\u914D\u7684\u5217 dataExchange.error.TableNotFoundException=\u8868\u201C{0}\u201D\u4E0D\u5B58\u5728 diff --git a/datagear-web/src/main/webapp/WEB-INF/view/dataexchange/export_csv.ftl b/datagear-web/src/main/webapp/WEB-INF/view/dataexchange/export_csv.ftl index 5561dca5..ae32d06b 100644 --- a/datagear-web/src/main/webapp/WEB-INF/view/dataexchange/export_csv.ftl +++ b/datagear-web/src/main/webapp/WEB-INF/view/dataexchange/export_csv.ftl @@ -43,7 +43,7 @@ Schema schema 数据库,不允许为null

<@spring.message code='dataExport.selectAndExportData' />

-
+
@@ -53,7 +53,7 @@ Schema schema 数据库,不允许为null
-
+
@@ -62,11 +62,12 @@ Schema schema 数据库,不允许为null
- - + + +
- + <@spring.message code='dataExport.exportFileEncoding' />
-
+
@@ -83,11 +83,11 @@ Schema schema 数据库,不允许为null
- - + +
- + <@spring.message code='dataImport.importFileEncoding' />