diff --git a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/annotation/ExcelColumn.java b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/annotation/ExcelColumn.java new file mode 100644 index 00000000..c82b803c --- /dev/null +++ b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/annotation/ExcelColumn.java @@ -0,0 +1,29 @@ +package com.jmsoftware.maf.springcloudstarter.annotation; + +import org.apache.poi.ss.usermodel.CellType; + +import java.lang.annotation.*; + +/** + * Description: ExcelColumn, change description here. + * + * @author 钟俊 (zhongjun), email: zhongjun@toguide.cn, date: 2/19/2021 9:15 AM + */ +@Documented +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExcelColumn { + /** + * Description string. + * + * @return the string + */ + String description() default ""; + + /** + * Cell type cell type. + * + * @return the cell type + */ + CellType cellType() default CellType.STRING; +} diff --git a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/controller/AbstractExcelImportController.java b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/controller/AbstractExcelImportController.java index ce84bb34..e99d3ea1 100644 --- a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/controller/AbstractExcelImportController.java +++ b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/controller/AbstractExcelImportController.java @@ -7,7 +7,9 @@ import com.jmsoftware.maf.common.bean.ResponseBodyBean; import com.jmsoftware.maf.springcloudstarter.util.PoiUtil; import io.swagger.annotations.ApiOperation; +import lombok.NonNull; import lombok.extern.slf4j.Slf4j; +import lombok.val; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.http.client.utils.DateUtils; @@ -36,76 +38,73 @@ /** *
Excel 表格数据导入抽象类。
- *经过 钟俊 (jun.zhong)
改造,给该类增添许多令人激动的新特性:
Abstract controller for excel data import.
+ *ExcelImportBeanType
。在 ExcelImportBeanType
中定义 Excel 表的中各个列数据(即表头);ExcelImportBeanType
中使用 @ExcelColumn
来对表头对中文名称进行标注,可以达到事半功倍对效果。还增加 Excel
- * 单元格类型的支持,默认为 Cell.CELL_TYPE_STRING
;AbstractExcelImportController<ExcelImportBeanType>
@ExcelColumn
for fields can be generating Excel easier than ever.理解生命周期有助于减少编写代码时出现意想不到的错误。以下是该类的生命周期的解释,参考方法引用:com.ucarinc.inner.asset.common.base
- * .AbstractExcelImportController#AbstractExcelImportController
、com.ucarinc.inner.asset.common.base
- * .AbstractExcelImportController#upload
。
初始化上下文。通过反射生成 ExcelImportBeanType 字段名称数组。
- *注册绑定方法。
- *注册默认匹配规则的校验方法。
- *默认不执行操作。可以被子类重写覆盖。
- *初始化当前线程的现场上下文,主要的工作有:
- *errorMessageList
错误信息列表、beanList
- * 实体类列表、returnMessageList
需要返回的信息列表、rowLocation
当前行位置、columnLocation
- * 当前列位置、sheetLocation
当前 Excel 表单位置、readingRowCount
总读取行数…Understanding of the lifecycle will help us make less mistakes during programming.
+ *Initialize context. Generate the field name array of ExcelImportBeanType by reflection.
+ *Register bind handler methods (starts with ‘“check”, like checkString()
).
Register default handler methods (starts with ‘“check”, like checkString()
).
Left black. Can be overridden by sub class.
+ *Initialize locale context for current thread. Main work below:
+ *执行插入数据前操作,默认不执行任何操作。可以被子类重写覆盖。
- *执行自定义的数据库操作。本方法为抽象方法,必须由子类实现。
- *当前面当生命周期中,发生了任何异常,该方法会被回调。本方法为抽象方法,必须由子类实现。
- *执行后钩子方法。删除文件。
- *销毁当前线程的现场环境。与 initLocaleContext()
相对应。
After initializing, will upload Excel, read and bind data, validate data.
+ *Left black. Can be overridden by sub class.
+ *Must be implemented by sub class.
+ *If any exceptions occur, this method will be called. Must be implemented by sub class.
+ *Delete temporary file.
+ *Destroy locale context, in opposite of initLocaleContext()
.
+ * Start with `check`, parameter is List list, return value is String or Boolean. *
* e.g public String checkName(List list)
*/
private final Map AbstractExcelImportController 的构造方法 Constructor of AbstractExcelImportController 执行默认的校验方法注册 Init context Register bind handler methods 执行默认的环境初始化 Register handler methods 注册默认匹配规则的校验方法。 Register handler methods e.g: private Boolean checkXXX(String value,Integer index) e.g: private String checkXXX(String value,Integer index) 检查是否符合默认匹配原则。 Check if method is valid for validation. 以 check 方法开头,接需要校验的属性字段名称; Method name starts with `check` 参数为 String value; Parameter is String value 返回值为 Boolean Return value is Boolean 初始化上下文。 Init context. 调用 调用 调用 Call 调用 Set fieldNameArray
+ * TODO: check the method if is necessary or not
*
* @param itemBytes the item bytes
* @param fileName the file name
@@ -525,7 +540,7 @@ private File uploadTempFile(byte[] itemBytes, String fileName) {
}
/**
- * 上传文件。
+ * Upload file.
*
* @param request the request
* @return File file
@@ -550,14 +565,13 @@ private File uploadFile(MultipartHttpServletRequest request) throws IOException
}
/**
- * 读取 Excel 文件置入 Workbook 实例对象中。
+ * Read the file into workbook.
*
- * @param file 需要读取的文件对象
- * @return Workbook workbook
+ * @param file the file
+ * @return the workbook
* @throws IOException the io exception
*/
- private Workbook readFile(File file) throws IOException {
- Assert.notNull(file, "file must not be null!");
+ private Workbook readFile(@NonNull File file) throws IOException {
Workbook workbook = null;
String extension = FilenameUtils.getExtension(file.getName());
if (XLS.equals(extension)) {
@@ -583,7 +597,8 @@ private void uploadFileToFtp(File file, String path) {
// InputStream in = new FileInputStream(file);
// ftp.connectServer();
// ftp.upload(path + DateUtils.formatDate(new Date(), "yyyyMM"), new String(file.getName().getBytes("GBK"),
-// StandardCharsets.ISO_8859_1), in);
+// StandardCharsets.ISO_8859_1),
+// in);
// } catch (IOException e) {
// log.error("上传文件至 FTP 时发生异常!异常信息:{}", e.getMessage());
// } finally {
@@ -592,92 +607,94 @@ private void uploadFileToFtp(File file, String path) {
}
/**
- * 过滤不需要处理的 sheet 页。默认所有 sheet 都处理。
+ * Filter sheet. In default, will proceed all sheets.
*
* @param sheet the sheet
* @return the boolean
*/
- protected boolean sheetFilter(Sheet sheet) {
+ protected boolean filterSheet(Sheet sheet) {
return true;
}
/**
- * 绑定数据到对象上。所做的工作有: Bind data from the workbook. Processes below: 依据 fieldNameArray 绑定数据至 bindClass 实例上 Bind data to the instance of bindClass, according to the fieldNameArray. 通过回调,校验字段的有效性 Validate the field by callback method> errorMessageList = new ThreadLocal<>();
/**
- * 最终解析完成的可操作数据列表
+ * Bean list. After reading Excel
*/
protected final ThreadLocal
> beanList = new ThreadLocal<>();
/**
- * 最终返回的消息集合
+ * Return message list
*/
private final ThreadLocal
> returnMessageList = new ThreadLocal<>();
/**
@@ -219,11 +220,13 @@ public void setFileName(String fileName) {
}
/**
- *
- *
*/
@@ -234,7 +237,7 @@ public AbstractExcelImportController() {
}
/**
- * 初始化当前线程的现场环境
+ * Init locale context.
*/
private void initLocaleContext() {
errorMessageList.set(new LinkedList<>());
@@ -254,7 +257,7 @@ private void initLocaleContext() {
protected abstract void onExceptionOccurred();
/**
- * 销毁当前线程的现场环境
+ * Destroy locale context.
*/
private void destroyLocaleContext() {
errorMessageList.remove();
@@ -273,59 +276,66 @@ private void destroyLocaleContext() {
}
/**
- * 上传文件
+ * Upload excel file. Any exceptions happened in any lifecycle will not interrupt the whole process.
*
* @param request the request
* @param response the response
- * @return String result
+ * @return the response body bean
*/
@PostMapping(value = "/upload", headers = "content-type=multipart/form-data")
- @ApiOperation(value = "上传 Excel 文件", notes = "上传 Excel 文件")
+ @ApiOperation(value = "Upload Excel file", notes = "Upload Excel file")
public ResponseBodyBean
- *
*/
private void registerHandlerMethods() {
- // 清除数据
this.checkMethodMap.clear();
- // 注册符合默认匹配原则的方法
+ // Register valid methods for validation
Method[] methods = this.getClass().getDeclaredMethods();
for (Method method : methods) {
if (isCheckMethod(method)) {
@@ -392,15 +400,18 @@ private void registerHandlerMethods() {
}
/**
- * private Boolean checkXXX(String value,Integer index)
private String checkXXX(String value,Integer index)
, the return value can be empty or
+ * “true”, or other error message which will be added to errorMessage
- *
+ *
+ * @param method the method
+ * @return the boolean
*/
private Boolean isCheckMethod(Method method) {
Class> returnType = method.getReturnType();
@@ -416,29 +427,24 @@ private Boolean isCheckMethod(Method method) {
}
/**
- * 注册校验方法
+ * Register check method.
*
- * @param method 将要被注册的方法对象
+ * @param method the method
*/
private void registerCheckMethod(Method method) {
String fieldName = method.getName().
substring(DEFAULT_CHECK_METHOD_PREFIX.length());
fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
this.checkMethodMap.put(fieldName, method);
- log.info("Register check method [" + method.getName() + "]");
+ log.info("Registered check method [" + method.getName() + "]");
}
/**
- *
- *
*/
@@ -450,14 +456,20 @@ protected void initContext() {
Field declaredField = declaredFields[index];
fieldNameArray[index] = declaredField.getName();
}
- log.info("通过反射生成 {} 字段名称数组:{}", bindClass.getSimpleName(), fieldNameArray);
+ log.info("Generated {} field name array by reflection, fieldNameArray: {}", bindClass.getSimpleName(),
+ fieldNameArray);
this.setFieldNameArray(fieldNameArray);
}
+ /**
+ * Gets generic class.
+ *
+ * @return the generic class
+ */
@SuppressWarnings("unchecked")
private ClasssetBindClass(Class<?> bindClass)
设置数据绑定类;setFieldNamesArray(String[] fieldNameArray)
设置数据绑定列(列名为绑定类中的属性名,顺序需和Excel导入的列顺序一致);registCustomCheckMethod(String fieldName,String methodName)
添加自定义名称校验方法(默认会注册特定名称的校验方法)
- * ;getGenericClass()
to set Excel import type;setIsDenyAll()
配置修改当校验出现失败情况时的操作。true 为全部回退,false 为校验失败的回退。默认为 true。
- *
*
* @param workbook the workbook
+ * @throws Exception the exception
*/
@SuppressWarnings("RedundantThrows")
private void bindData(Workbook workbook) throws Exception {
for (int k = 0; k < workbook.getNumberOfSheets(); k++) {
Sheet sheet = workbook.getSheetAt(k);
- // 过滤掉不需要处理的 sheet 页
- if (!sheetFilter(sheet)) {
+ if (!filterSheet(sheet)) {
continue;
}
- // 指定当前 sheet 位置
+ // Specify current sheet location
sheetLocation.set(k + 1);
sheet.getSheetName();
- // 计算总记录数
+ // Set Reading row count
readingRowCount.set(readingRowCount.get() + sheet.getLastRowNum() - sheet.getFirstRowNum());
- // 验证导入数量是否大于最大值
+ // Check if exceeding the MAXIMUM_ROW_COUNT
if (readingRowCount.get() > MAXIMUM_ROW_COUNT) {
- setErrorMessage(String.format("导入条数不能大于 %d 条(表头也计入行数)!当前总条数:%d", MAXIMUM_ROW_COUNT,
- readingRowCount.get()));
+ setErrorMessage(String.format(
+ "The amount of importing data cannot be greater than %d (Table head included)! " +
+ "Current reading row count: %d", MAXIMUM_ROW_COUNT, readingRowCount.get()));
continue;
}
- // 验证导入数量是否大于最大值
+ // Check if the readingRowCount is equal to zero
if (readingRowCount.get() == 0) {
- setErrorMessage("没有可导入的数据,请检查。");
+ setErrorMessage("Not available data to import. Check Excel again.");
continue;
}
- // 获取开始结束位置
+ // Check if the first row is equal to null
if (sheet.getRow(0) == null) {
- // sheet 页格式不合法,没有标题,本页不解析
- setErrorMessage(String.format("第 %d 页表单格式不合法,没有标题。", sheetLocation.get()));
+ setErrorMessage(String.format("Sheet [%s] (No. %d) format is invalid: no title! ", sheet.getSheetName(),
+ sheetLocation.get()));
+ // If the sheet is not valid, then skip it
continue;
}
int startIndex = sheet.getRow(0).getFirstCellNum();
int endIndex = sheet.getRow(0).getLastCellNum();
- // 从第二行开始解析
+ // Parse from the second row
for (int i = sheet.getFirstRowNum() + 1; i <= sheet.getLastRowNum(); i++) {
- // 指定当前坐标X
+ // Specify current row location
rowLocation.set(i + 1);
Row row = sheet.getRow(i);
if (isBlankRow(row)) {
- // 空行不计入总行数
+ // Blank row will not be considered as a effective row, not be included in `readingRowCount`
readingRowCount.set(readingRowCount.get() - 1);
continue;
}
- // 绑定到实例 bean
+ // Bind row to bean
bindRowToBean(row, startIndex, endIndex);
}
}
}
/**
- * 判断是否为空行
+ * Check if the row is blank. If there is one cell of the row is not blank, then the row is not blank.
*
* @param row the row
- * @return the boolean
+ * @return true if the row is blank; or vice versa.
*/
private boolean isBlankRow(Row row) {
if (row == null) {
return true;
}
- boolean result = true;
- for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
- Cell cell = row.getCell(i, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
- String value = "";
+ Cell cell;
+ var value = "";
+ for (var i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
+ cell = row.getCell(i, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
if (cell != null) {
switch (cell.getCellType()) {
case STRING:
- value = cell.getStringCellValue();
+ value = cell.getStringCellValue().trim();
break;
case NUMERIC:
value = String.valueOf((int) cell.getNumericCellValue());
@@ -691,41 +708,40 @@ private boolean isBlankRow(Row row) {
default:
break;
}
- if (!"".equals(value.trim())) {
- result = false;
- break;
+ if (StrUtil.isNotBlank(value)) {
+ return false;
}
}
}
- return result;
+ return true;
}
/**
- * 绑定行到数据对象上
+ * Bind row to bean.
*
- * @param row Row
+ * @param row the row
* @param startIndex the start index
* @param endIndex the end index
*/
private void bindRowToBean(Row row, int startIndex, int endIndex) {
Assert.notNull(this.bindClass, "bindClass must not be null!");
Assert.notNull(this.fieldNameArray, "fieldNameArray must not be null!");
- boolean bindingResult = false;
+ var bindingResult = false;
try {
- // 新建数据实例
- ExcelImportBeanType bean = this.bindClass.getDeclaredConstructor().newInstance();
- Field[] fields = this.bindClass.getDeclaredFields();
- for (int i = startIndex; i < endIndex; i++) {
- // 出现多余数据,则当前行绑定失效
- if (i >= fieldNameArray.length) {
+ // New bean instance
+ val bean = this.bindClass.getDeclaredConstructor().newInstance();
+ val fields = this.bindClass.getDeclaredFields();
+ for (var index = startIndex; index < endIndex; index++) {
+ // If found more data, then binding failed
+ if (index >= fieldNameArray.length) {
bindingResult = false;
- setErrorMessage(String.format("第 %d 行存在多余数据,请检查。", rowLocation.get()));
+ setErrorMessage(
+ String.format("Found redundant data on row number %d. Check again.", rowLocation.get()));
break;
}
- // 获取需要绑定的属性名称
+ // Get the field that needs binding
Field field = null;
- String fieldName = fieldNameArray[i];
- // 获取需要绑定的Field实例
+ val fieldName = fieldNameArray[index];
for (Field f : fields) {
if (f.getName().equals(fieldName)) {
field = f;
@@ -733,30 +749,30 @@ private void bindRowToBean(Row row, int startIndex, int endIndex) {
}
}
if (field != null) {
- String value = getCellValue2String(row.getCell(i));
- // 绑定开始
- // 指定当前坐标Y
- columnLocation.set(i + 1);
- // 执行自定义校验
- Method method = this.checkMethodMap.get(fieldName);
+ val value = getCellValue2String(row.getCell(index));
+ // Start to bind
+ // Specify current column location
+ columnLocation.set(index + 1);
+ // Execute custom validation method
+ val method = this.checkMethodMap.get(fieldName);
Object returnObj = null;
if (method != null) {
method.setAccessible(true);
returnObj = method.invoke(this, value, rowLocation.get(), bean);
method.setAccessible(false);
}
- String returnStr = returnObj == null ? null : returnObj.toString();
- if (null == returnStr || "".equals(returnStr) || "true".equals(returnStr)) {
- // 执行数据绑定
+ val validationResult = returnObj == null ? null : returnObj.toString();
+ // If `validationResult` is blank or equal to "true"
+ if (StrUtil.isBlank(validationResult) || Boolean.TRUE.toString().equals(validationResult)) {
bindingResult = bind(value, field, bean);
} else {
bindingResult = false;
- // 添加自定义校验错误信息
- if (!"false".equals(returnStr)) {
- setErrorMessage(returnStr);
+ // If `validationResult` is not equal to "false" then add to error message list
+ if (!Boolean.FALSE.toString().equals(validationResult)) {
+ setErrorMessage(validationResult);
}
}
- // 绑定结束
+ // Finished binding
if (!bindingResult) {
break;
}
@@ -773,7 +789,9 @@ private void bindRowToBean(Row row, int startIndex, int endIndex) {
} catch (Exception e) {
log.error("bindRowToBean method has encountered a problem!", e);
exceptionOccurred.set(true);
- String errorMessage = String.format("绑定并校验第 %d 行数据时发生异常,异常信息:%s", rowLocation.get(), e.getMessage());
+ String errorMessage = String.format(
+ "Exception occurred when binding and validating the data of row number %d. " +
+ "Exception message: %s", rowLocation.get(), e.getMessage());
setErrorMessage(errorMessage);
short lastCellNum = row.getLastCellNum();
Cell errorInformationCell = row.createCell(fieldNameArray.length);
@@ -785,10 +803,10 @@ private void bindRowToBean(Row row, int startIndex, int endIndex) {
}
/**
- * 转换单元格信息为 String 字符创
+ * Gets cell value 2 string.
*
* @param cell the cell
- * @return the cell value 2 string
+ * @return the string
*/
private String getCellValue2String(Cell cell) {
String returnString = "";
@@ -797,17 +815,17 @@ private String getCellValue2String(Cell cell) {
case BLANK:
return "";
case NUMERIC:
- // 如果为输入为日期格式
+ // If it's date
if (DateUtil.isCellDateFormatted(cell)) {
- Date date = cell.getDateCellValue();
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ val date = cell.getDateCellValue();
+ val dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
returnString = dateFormat.format(date);
} else {
- BigDecimal bg = new BigDecimal(String.valueOf(cell.getNumericCellValue()).trim());
- // 若小数部分为 0 则仅保留整数部分
- String tempStr = bg.toPlainString();
- int dotIndex = tempStr.indexOf(".");
- if ((bg.doubleValue() - bg.longValue()) == 0 && dotIndex > 0) {
+ val bigDecimal = new BigDecimal(String.valueOf(cell.getNumericCellValue()).trim());
+ // Keep decimal fraction parts which are not zero
+ val tempStr = bigDecimal.toPlainString();
+ val dotIndex = tempStr.indexOf(".");
+ if ((bigDecimal.doubleValue() - bigDecimal.longValue()) == 0 && dotIndex > 0) {
returnString = tempStr.substring(0, dotIndex);
} else {
returnString = tempStr;
@@ -826,9 +844,9 @@ private String getCellValue2String(Cell cell) {
}
/**
- * 注册绑定方法
+ * Register bind handler methods.
*/
- protected void registerBindHandlerMethods() {
+ private void registerBindHandlerMethods() {
try {
Method bindStringField = ReflectionUtils.findMethod(this.getClass(),
"bindStringField",
@@ -872,12 +890,12 @@ protected void registerBindHandlerMethods() {
}
/**
- * 实际绑定动作
+ * Real binding value to the bean's field.
*
- * @param value Excel 文件对应单元格数据的字符串形式
- * @param field 将要绑定到的 bean 的对应属性对象
- * @param bean 将要绑定到的 bean
- * @return the boolean
+ * @param value the string value of the excel cell
+ * @param field the the field of the bean
+ * @param bean the bean
+ * @return true if the binding succeeded, or vice versa.
* @throws RuntimeException the runtime exception
*/
private Boolean bind(String value, Field field, Object bean) throws RuntimeException {
@@ -890,10 +908,10 @@ private Boolean bind(String value, Field field, Object bean) throws RuntimeExcep
try {
result = (Boolean) bindMethod.invoke(this, value, field, bean);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- StringBuilder exceptionMessage = new StringBuilder("绑定数据时发生异常!");
+ val exceptionMessage = new StringBuilder("Exception occurred when binding! ");
if (!StrUtil.isBlank(e.getMessage())) {
log.error("Exception occurred when invoking method!", e);
- exceptionMessage.append(e.getMessage());
+ exceptionMessage.append(e.getMessage()).append(" ");
}
if (ObjectUtil.isNotNull(e.getCause()) && !StrUtil.isBlank(e.getCause().getMessage())) {
log.error("Exception occurred when invoking method!", e.getCause());
@@ -908,7 +926,7 @@ private Boolean bind(String value, Field field, Object bean) throws RuntimeExcep
}
/**
- * 绑定 int,Integer 属性
+ * Bind int field boolean.
*
* @param value the value
* @param field the field
@@ -927,8 +945,9 @@ private Boolean bindIntField(String value, Field field, Object bean) throws Ille
field.set(bean, realValue);
field.setAccessible(false);
} catch (NumberFormatException e) {
- log.error("绑定 int,Integer 属性时发生异常!异常信息:{}。Value:{},field:{}", e.getMessage(), value, field.getName());
- String formattedMessage = String.format("第 %d 行,第 %d 列数据格式有误,须为整数,请校对后重新导入。",
+ log.error("Exception occurred when binding int/Integer field! Exception message: {}, value: {}, field: {}",
+ e.getMessage(), value, field.getName());
+ String formattedMessage = String.format("Invalid data of the row %d, col %d, must be integer",
rowLocation.get(), columnLocation.get());
setErrorMessage(formattedMessage);
throw new IllegalArgumentException(formattedMessage);
@@ -936,9 +955,8 @@ private Boolean bindIntField(String value, Field field, Object bean) throws Ille
return true;
}
-
/**
- * 绑定 long,Long 属性
+ * Bind long field boolean.
*
* @param value the value
* @param field the field
@@ -948,7 +966,7 @@ private Boolean bindIntField(String value, Field field, Object bean) throws Ille
*/
private Boolean bindLongField(String value, Field field, Object bean) throws IllegalAccessException {
try {
- Long realValue = value == null ? null : (long) Double.parseDouble(value);
+ var realValue = value == null ? null : (long) Double.parseDouble(value);
if (realValue == null && field.getType() == long.class) {
realValue = 0L;
}
@@ -956,8 +974,9 @@ private Boolean bindLongField(String value, Field field, Object bean) throws Ill
field.set(bean, realValue);
field.setAccessible(false);
} catch (NumberFormatException e) {
- log.error("绑定 long,Long 属性时发生异常!异常信息:{}。Value:{},field:{}", e.getMessage(), value, field.getName());
- String formattedMessage = String.format("第 %d 行,第 %d 列数据格式有误,须为整数,请校对后重新导入。",
+ log.error("Exception occurred when binding long/Long field! Exception message: {}, value: {}, field: {}",
+ e.getMessage(), value, field.getName());
+ String formattedMessage = String.format("Invalid data of the row %d, col %d, must be long integer",
rowLocation.get(), columnLocation.get());
setErrorMessage(formattedMessage);
throw new IllegalArgumentException(formattedMessage);
@@ -966,7 +985,7 @@ private Boolean bindLongField(String value, Field field, Object bean) throws Ill
}
/**
- * 绑定 float,Float 属性
+ * Bind long field boolean.
*
* @param value the value
* @param field the field
@@ -974,18 +993,15 @@ private Boolean bindLongField(String value, Field field, Object bean) throws Ill
* @return the boolean
* @throws IllegalAccessException the illegal access exception
*/
- private Boolean bindFloatField(String value, Field field, Object bean) throws IllegalAccessException {
+ private Boolean bindLongField(Long value, Field field, Object bean) throws IllegalAccessException {
try {
- Float realValue = value == null ? null : Float.parseFloat(value);
- if (realValue == null && field.getType() == float.class) {
- realValue = 0F;
- }
field.setAccessible(true);
- field.set(bean, realValue);
+ field.set(bean, value);
field.setAccessible(false);
- } catch (NumberFormatException e) {
- log.error("绑定 float,Float 属性时发生异常!异常信息:{}。Value:{},field:{}", e.getMessage(), value, field.getName());
- String formattedMessage = String.format("第 %d 行,第 %d 列数据格式有误,须为单精度浮点数,请校对后重新导入。",
+ } catch (IllegalArgumentException e) {
+ log.error("Exception occurred when binding Long field! Exception message: {}, value: {}, field: {}",
+ e.getMessage(), value, field.getName());
+ String formattedMessage = String.format("Invalid data of the row %d, col %d, must be Long integer",
rowLocation.get(), columnLocation.get());
setErrorMessage(formattedMessage);
throw new IllegalArgumentException(formattedMessage);
@@ -993,9 +1009,8 @@ private Boolean bindFloatField(String value, Field field, Object bean) throws Il
return true;
}
-
/**
- * 绑定 double,Double 属性
+ * Bind float field boolean.
*
* @param value the value
* @param field the field
@@ -1003,18 +1018,19 @@ private Boolean bindFloatField(String value, Field field, Object bean) throws Il
* @return the boolean
* @throws IllegalAccessException the illegal access exception
*/
- private Boolean bindDoubleField(String value, Field field, Object bean) throws IllegalAccessException {
+ private Boolean bindFloatField(String value, Field field, Object bean) throws IllegalAccessException {
try {
- Double realValue = value == null ? null : Double.parseDouble(value);
- if (realValue == null && field.getType() == double.class) {
- realValue = 0D;
+ Float realValue = value == null ? null : Float.parseFloat(value);
+ if (realValue == null && field.getType() == float.class) {
+ realValue = 0F;
}
field.setAccessible(true);
field.set(bean, realValue);
field.setAccessible(false);
} catch (NumberFormatException e) {
- log.error("绑定 double,Double 属性时发生异常!异常信息:{}。Value:{},field:{}", e.getMessage(), value, field.getName());
- String formattedMessage = String.format("第 %d 行,第 %d 列数据格式有误,须为双精度浮点数,请校对后重新导入。",
+ log.error("Exception occurred when binding float/Float field! Exception message: {}, value: {}, field: {}",
+ e.getMessage(), value, field.getName());
+ String formattedMessage = String.format("Invalid data of the row %d, col %d, must be float",
rowLocation.get(), columnLocation.get());
setErrorMessage(formattedMessage);
throw new IllegalArgumentException(formattedMessage);
@@ -1023,7 +1039,7 @@ private Boolean bindDoubleField(String value, Field field, Object bean) throws I
}
/**
- * 绑定 String 属性
+ * Bind double field boolean.
*
* @param value the value
* @param field the field
@@ -1031,14 +1047,19 @@ private Boolean bindDoubleField(String value, Field field, Object bean) throws I
* @return the boolean
* @throws IllegalAccessException the illegal access exception
*/
- private Boolean bindStringField(String value, Field field, Object bean) throws IllegalAccessException {
+ private Boolean bindDoubleField(String value, Field field, Object bean) throws IllegalAccessException {
try {
+ Double realValue = value == null ? null : Double.parseDouble(value);
+ if (realValue == null && field.getType() == double.class) {
+ realValue = 0D;
+ }
field.setAccessible(true);
- field.set(bean, value);
+ field.set(bean, realValue);
field.setAccessible(false);
- } catch (IllegalArgumentException e) {
- log.error("绑定 String 属性时发生异常!异常信息:{}。Value:{},field:{}", e.getMessage(), value, field.getName());
- String formattedMessage = String.format("第 %d 行,第 %d 列数据格式有误,须为字符串,请校对后重新导入。",
+ } catch (NumberFormatException e) {
+ log.error("Exception occurred when binding double/Double field! Exception message: {}, value: {}, field: {}",
+ e.getMessage(), value, field.getName());
+ String formattedMessage = String.format("Invalid data of the row %d, col %d, must be double",
rowLocation.get(), columnLocation.get());
setErrorMessage(formattedMessage);
throw new IllegalArgumentException(formattedMessage);
@@ -1047,7 +1068,7 @@ private Boolean bindStringField(String value, Field field, Object bean) throws I
}
/**
- * 绑定 Long 属性
+ * Bind string field boolean.
*
* @param value the value
* @param field the field
@@ -1055,14 +1076,15 @@ private Boolean bindStringField(String value, Field field, Object bean) throws I
* @return the boolean
* @throws IllegalAccessException the illegal access exception
*/
- private Boolean bindLongField(Long value, Field field, Object bean) throws IllegalAccessException {
+ private Boolean bindStringField(String value, Field field, Object bean) throws IllegalAccessException {
try {
field.setAccessible(true);
field.set(bean, value);
field.setAccessible(false);
} catch (IllegalArgumentException e) {
- log.error("绑定 Long 属性时发生异常!异常信息:{}。Value:{},field:{}", e.getMessage(), value, field.getName());
- String formattedMessage = String.format("第 %d 行,第 %d 列数据格式有误,须为字符串,请校对后重新导入。",
+ log.error("Exception occurred when binding String field! Exception message: {}, value: {}, field: {}",
+ e.getMessage(), value, field.getName());
+ String formattedMessage = String.format("Invalid data of the row %d, col %d, must be string",
rowLocation.get(), columnLocation.get());
setErrorMessage(formattedMessage);
throw new IllegalArgumentException(formattedMessage);
@@ -1071,7 +1093,7 @@ private Boolean bindLongField(Long value, Field field, Object bean) throws Illeg
}
/**
- * 绑定 Date 属性
+ * Bind date field boolean.
*
* @param value the value
* @param field the field
@@ -1087,8 +1109,9 @@ private Boolean bindDateField(String value, Field field, Object bean) throws Ill
field.set(bean, date);
field.setAccessible(false);
} catch (ParseException e) {
- log.error("绑定 Date 属性时发生异常!异常信息:{}。Value:{},field:{}", e.getMessage(), value, field.getName());
- String formattedMessage = String.format("第 %d 行,第 %d 列数据格式有误,须为 yyyy-MM-dd HH:mm 日期形式,请校对后重新导入。",
+ log.error("Exception occurred when binding Date field! Exception message: {}, value: {}, field: {}",
+ e.getMessage(), value, field.getName());
+ String formattedMessage = String.format("Invalid data of the row %d, col %d, must be date",
rowLocation.get(), columnLocation.get());
setErrorMessage(formattedMessage);
throw new IllegalArgumentException(formattedMessage);
@@ -1097,18 +1120,18 @@ private Boolean bindDateField(String value, Field field, Object bean) throws Ill
}
/**
- * 允许通过配置修改当校验出现失败情况时的操作
+ * Sets deny all. When exception occurred, deny all data or not
*
- * @param denyAll 出现异常时是否需要拒绝所有已经校验成功的 bean,true 为拒绝,false为不拒绝
+ * @param denyAll the deny all
*/
public void setDenyAll(Boolean denyAll) {
this.denyAll = denyAll;
}
/**
- * 可以使用该方法添加自定义校验错误信息
+ * Sets error message.
*
- * @param errorInfo 错误信息
+ * @param errorInfo the error info
*/
protected void setErrorMessage(String errorInfo) {
this.errorMessageList.get().add(errorInfo);
@@ -1116,11 +1139,11 @@ protected void setErrorMessage(String errorInfo) {
}
/**
- * 可以使用该方法添加自定义返回页面消息错误信息
+ * Sets return message list.
*
- * @param msg the msg
+ * @param message the message
*/
- protected void setReturnMessageList(String msg) {
- this.returnMessageList.get().add(msg);
+ protected void setReturnMessageList(String message) {
+ this.returnMessageList.get().add(message);
}
}