From 306e34494c99318ce77ce5886c7bc959e74003df Mon Sep 17 00:00:00 2001 From: chenjianxing Date: Mon, 18 May 2020 15:48:16 +0800 Subject: [PATCH] =?UTF-8?q?JSR-303=E6=A0=A1=E9=AA=8C=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/metersphere/config/I18nConfig.java | 16 ++++++++++ .../excel/domain/TestCaseExcelData.java | 8 ++--- .../excel/listener/EasyExcelListener.java | 30 +++++++++++++------ .../excel/listener/TestCaseDataListener.java | 23 ++++++++------ .../excel/utils/ExcelValidateHelper.java | 16 +++++----- .../track/service/TestCaseService.java | 10 ++++--- .../main/resources/i18n/messages.properties | 14 ++++++++- .../resources/i18n/messages_en_US.properties | 14 ++++++++- .../resources/i18n/messages_zh_CN.properties | 11 +++++++ 9 files changed, 107 insertions(+), 35 deletions(-) diff --git a/backend/src/main/java/io/metersphere/config/I18nConfig.java b/backend/src/main/java/io/metersphere/config/I18nConfig.java index 546726892..f4a8d108d 100644 --- a/backend/src/main/java/io/metersphere/config/I18nConfig.java +++ b/backend/src/main/java/io/metersphere/config/I18nConfig.java @@ -3,8 +3,12 @@ package io.metersphere.config; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.i18n.Translator; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; + +import javax.validation.Validator; @Configuration public class I18nConfig { @@ -20,4 +24,16 @@ public class I18nConfig { public CommonBeanFactory commonBeanFactory() { return new CommonBeanFactory(); } + + /** + * JSR-303校验国际化 + * @param messageSource + * @return + */ + @Bean + public LocalValidatorFactoryBean localValidatorFactoryBean(MessageSource messageSource) { + LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); + localValidatorFactoryBean.setValidationMessageSource(messageSource); + return localValidatorFactoryBean; + } } diff --git a/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelData.java b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelData.java index c04bea2fc..22771289c 100644 --- a/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelData.java +++ b/backend/src/main/java/io/metersphere/excel/domain/TestCaseExcelData.java @@ -20,12 +20,12 @@ public class TestCaseExcelData { @Length(max=1000) @ExcelProperty("所属模块") @ColumnWidth(30) - @Pattern(regexp = "^(?!.*//).*$", message = "格式不正确") + @Pattern(regexp = "^(?!.*//).*$", message = "{incorrect_format}") private String nodePath; @NotBlank @ExcelProperty("用例类型") - @Pattern(regexp = "(^functional$)|(^performance$)|(^api$)", message = "必须为functional、performance、api") + @Pattern(regexp = "(^functional$)|(^performance$)|(^api$)", message = "{test_case_type_validate}") private String type; @NotBlank @@ -34,12 +34,12 @@ public class TestCaseExcelData { @NotBlank @ExcelProperty("优先级") - @Pattern(regexp = "(^P0$)|(^P1$)|(^P2$)|(^P3$)", message = "必须为P0、P1、P2、P3") + @Pattern(regexp = "(^P0$)|(^P1$)|(^P2$)|(^P3$)", message = "{test_case_priority_validate}") private String priority; @NotBlank @ExcelProperty("测试方式") - @Pattern(regexp = "(^manual$)|(^auto$)", message = "必须为manual、auto") + @Pattern(regexp = "(^manual$)|(^auto$)", message = "{test_case_method_validate}") private String method; @ColumnWidth(50) diff --git a/backend/src/main/java/io/metersphere/excel/listener/EasyExcelListener.java b/backend/src/main/java/io/metersphere/excel/listener/EasyExcelListener.java index 1d95d382b..e65197960 100644 --- a/backend/src/main/java/io/metersphere/excel/listener/EasyExcelListener.java +++ b/backend/src/main/java/io/metersphere/excel/listener/EasyExcelListener.java @@ -8,11 +8,16 @@ import com.alibaba.excel.util.StringUtils; import io.metersphere.commons.utils.LogUtil; import io.metersphere.excel.utils.ExcelValidateHelper; import io.metersphere.excel.domain.ExcelErrData; +import io.metersphere.i18n.Translator; +import org.springframework.stereotype.Component; +import javax.annotation.Resource; import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.*; - +@Component public abstract class EasyExcelListener extends AnalysisEventListener { protected List> errList = new ArrayList<>(); @@ -26,9 +31,12 @@ public abstract class EasyExcelListener extends AnalysisEventListener { protected Class clazz; + @Resource + ExcelValidateHelper excelValidateHelper; - public EasyExcelListener(Class clazz){ - this.clazz = clazz; + public EasyExcelListener(){ + Type type = getClass().getGenericSuperclass(); + this.clazz = (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; } /** @@ -43,16 +51,18 @@ public abstract class EasyExcelListener extends AnalysisEventListener { Integer rowIndex = analysisContext.readRowHolder().getRowIndex(); try { //根据excel数据实体中的javax.validation + 正则表达式来校验excel数据 - errMsg = ExcelValidateHelper.validateEntity(t); + errMsg = excelValidateHelper.validateEntity(t); //自定义校验规则 errMsg = validate(t, errMsg); } catch (NoSuchFieldException e) { - errMsg = "解析数据出错"; + errMsg = Translator.get("parse_data_error"); LogUtil.error(e.getMessage(), e); } if (!StringUtils.isEmpty(errMsg)) { - ExcelErrData excelErrData = new ExcelErrData(t, rowIndex, "第" + rowIndex + "行出错:" + errMsg); + ExcelErrData excelErrData = new ExcelErrData(t, rowIndex, + Translator.get("number") + rowIndex + Translator.get("row") + Translator.get("erroer") + + ":" + errMsg); errList.add(excelErrData); } else { list.add(t); @@ -101,7 +111,7 @@ public abstract class EasyExcelListener extends AnalysisEventListener { Collection values = headMap.values(); for (String key : fieldNameSet) { if (!values.contains(key)){ - throw new ExcelAnalysisException("缺少头部信息:" + key); + throw new ExcelAnalysisException(Translator.get("missing_header_information") + ":" + key); } } } catch (NoSuchFieldException e) { @@ -133,8 +143,10 @@ public abstract class EasyExcelListener extends AnalysisEventListener { } - public List> getErrList() { - return errList; + public List> getAndClearErrList() { + List> tmp = this.errList; + this.errList = new ArrayList<>(); + return tmp; } } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java b/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java index c9df3b95e..350c9b6fa 100644 --- a/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java +++ b/backend/src/main/java/io/metersphere/excel/listener/TestCaseDataListener.java @@ -6,18 +6,22 @@ import io.metersphere.excel.domain.TestCaseExcelData; import io.metersphere.base.domain.TestCaseWithBLOBs; import io.metersphere.commons.constants.TestCaseConstants; import io.metersphere.commons.utils.BeanUtils; +import io.metersphere.i18n.Translator; import io.metersphere.track.service.TestCaseService; import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import javax.annotation.Resource; import java.util.List; import java.util.Set; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; - +@Component public class TestCaseDataListener extends EasyExcelListener { + @Resource private TestCaseService testCaseService; private String projectId; @@ -26,13 +30,13 @@ public class TestCaseDataListener extends EasyExcelListener { Set userIds; - public TestCaseDataListener(TestCaseService testCaseService, String projectId, - Set testCaseNames, Set userIds, Class clazz) { - super(clazz); - this.testCaseService = testCaseService; + public TestCaseDataListener() {} + + public TestCaseDataListener init(String projectId, Set testCaseNames, Set userIds) { this.projectId = projectId; this.testCaseNames = testCaseNames; this.userIds = userIds; + return this; } @Override @@ -43,21 +47,22 @@ public class TestCaseDataListener extends EasyExcelListener { if (nodePath != null) { String[] nodes = nodePath.split("/"); if ( nodes.length > TestCaseConstants.MAX_NODE_DEPTH + 1) { - stringBuilder.append("节点最多为" + TestCaseConstants.MAX_NODE_DEPTH + "层;"); + stringBuilder.append(Translator.get("test_case_node_level_tip") + + TestCaseConstants.MAX_NODE_DEPTH + Translator.get("test_case_node_level")); } for (int i = 0; i < nodes.length; i++) { if (i != 0 && StringUtils.equals(nodes[i].trim(), "")) { - stringBuilder.append("所属模块不能为空格"); + stringBuilder.append(Translator.get("module_not_null")); break; } } } if (!userIds.contains(data.getMaintainer())) { - stringBuilder.append("该工作空间下无该用户:" + data.getMaintainer() + ";"); + stringBuilder.append(Translator.get("user_not_exists") + ":" + data.getMaintainer() + "; "); } if (testCaseNames.contains(data.getName())) { - stringBuilder.append("该项目下已存在该测试用例:" + data.getName() + ";"); + stringBuilder.append(Translator.get("test_case_already_exists") + ":" + data.getName() + "; "); } return stringBuilder.toString(); } diff --git a/backend/src/main/java/io/metersphere/excel/utils/ExcelValidateHelper.java b/backend/src/main/java/io/metersphere/excel/utils/ExcelValidateHelper.java index e4e29fa14..6bacd4a92 100644 --- a/backend/src/main/java/io/metersphere/excel/utils/ExcelValidateHelper.java +++ b/backend/src/main/java/io/metersphere/excel/utils/ExcelValidateHelper.java @@ -1,30 +1,32 @@ package io.metersphere.excel.utils; import com.alibaba.excel.annotation.ExcelProperty; +import org.springframework.stereotype.Component; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; +import javax.annotation.Resource; import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; import javax.validation.groups.Default; import java.lang.reflect.Field; import java.util.Set; - +@Component public class ExcelValidateHelper { private ExcelValidateHelper(){} - private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); + @Resource + LocalValidatorFactoryBean localValidatorFactoryBean; - public static String validateEntity(T obj) throws NoSuchFieldException { + public String validateEntity(T obj) throws NoSuchFieldException { StringBuilder result = new StringBuilder(); - Set> set = validator.validate(obj, Default.class); + Set> set = localValidatorFactoryBean.getValidator().validate(obj, Default.class); if (set != null && !set.isEmpty()) { for (ConstraintViolation cv : set) { Field declaredField = obj.getClass().getDeclaredField(cv.getPropertyPath().toString()); ExcelProperty annotation = declaredField.getAnnotation(ExcelProperty.class); //拼接错误信息,包含当前出错数据的标题名字+错误信息 - result.append(annotation.value()[0]+cv.getMessage()).append(";"); + result.append(annotation.value()[0]+cv.getMessage()).append("; "); } } return result.toString(); diff --git a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java index e1a3f7445..a509c1441 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestCaseService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestCaseService.java @@ -60,6 +60,9 @@ public class TestCaseService { @Resource TestCaseNodeService testCaseNodeService; + @Resource + TestCaseDataListener testCaseDataListener; + @Resource UserMapper userMapper; @@ -187,11 +190,10 @@ public class TestCaseService { List users = userMapper.selectByExample(userExample); Set userIds = users.stream().map(User::getId).collect(Collectors.toSet()); - EasyExcelListener easyExcelListener = new TestCaseDataListener(this, projectId, - testCaseNames, userIds, TestCaseExcelData.class); - EasyExcelFactory.read(file.getInputStream(), TestCaseExcelData.class, easyExcelListener).sheet().doRead(); + EasyExcelFactory.read(file.getInputStream(), TestCaseExcelData.class, + testCaseDataListener.init(projectId, testCaseNames, userIds)).sheet().doRead(); - List> errList = easyExcelListener.getErrList(); + List> errList = testCaseDataListener.getAndClearErrList(); //如果包含错误信息就导出错误信息 if (!errList.isEmpty()) { excelResponse.setSuccess(false); diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index 9ed63647c..9cb68664b 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -5,4 +5,16 @@ test_case_node_level= test_case_module_not_null= test_case_create_moule_fail= test_case_import_template_name= -test_case_import_template_sheet= \ No newline at end of file +test_case_import_template_sheet= +module_not_null= +user_not_exists= +test_case_already_exists= +parse_data_error= +missing_header_information= +number= +row= +erroer= +incorrect_format= +test_case_type_validate= +test_case_priority_validate= +test_case_method_validate= \ No newline at end of file diff --git a/backend/src/main/resources/i18n/messages_en_US.properties b/backend/src/main/resources/i18n/messages_en_US.properties index 2c259c586..3e9b591fe 100644 --- a/backend/src/main/resources/i18n/messages_en_US.properties +++ b/backend/src/main/resources/i18n/messages_en_US.properties @@ -39,4 +39,16 @@ test_case_node_level=level test_case_module_not_null=The owned module cannot be empty test_case_create_moule_fail=Failed to create module test_case_import_template_name=Test case templates -test_case_import_template_sheet=Template \ No newline at end of file +test_case_import_template_sheet=Template +module_not_null=The module must not be blank +user_not_exists=The user in this workspace is not exists +test_case_already_exists=The test case in this project is exists +parse_data_error=Parse data error +missing_header_information=Missing header information +number=Number +row=row +erroer=erroer +incorrect_format=Incorrect format +test_case_type_validate=must be functional, performance, api +test_case_priority_validate=must be P0, P1, P2, P3 +test_case_method_validate=\ must be manual, auto \ No newline at end of file diff --git a/backend/src/main/resources/i18n/messages_zh_CN.properties b/backend/src/main/resources/i18n/messages_zh_CN.properties index 4272998a6..97bb1d748 100644 --- a/backend/src/main/resources/i18n/messages_zh_CN.properties +++ b/backend/src/main/resources/i18n/messages_zh_CN.properties @@ -41,4 +41,15 @@ test_case_module_not_null=所属模块不能为空 test_case_create_moule_fail=创建模块失败 test_case_import_template_name=测试用例模版 test_case_import_template_sheet=模版 +module_not_null=所属模块不能为空格 +user_not_exists=该工作空间下无该用户 +test_case_already_exists=该项目下已存在该测试用例 +parse_data_error=解析数据出错 +missing_header_information=缺少头部信息 +number=第 +row=行 +incorrect_format=格式不正确 +test_case_type_validate=必须为functional、performance、api +test_case_priority_validate=必须为P0、P1、P2、P3 +test_case_method_validate=必须为manual、auto #test case end \ No newline at end of file -- GitLab