JSR-303校验国际化
This commit is contained in:
parent
64d6d11f11
commit
306e34494c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 <T> extends AnalysisEventListener<T> {
|
||||
|
||||
protected List<ExcelErrData<T>> errList = new ArrayList<>();
|
||||
|
@ -26,9 +31,12 @@ public abstract class EasyExcelListener <T> extends AnalysisEventListener<T> {
|
|||
|
||||
protected Class<T> clazz;
|
||||
|
||||
@Resource
|
||||
ExcelValidateHelper excelValidateHelper;
|
||||
|
||||
public EasyExcelListener(Class<T> clazz){
|
||||
this.clazz = clazz;
|
||||
public EasyExcelListener(){
|
||||
Type type = getClass().getGenericSuperclass();
|
||||
this.clazz = (Class<T>) ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,16 +51,18 @@ public abstract class EasyExcelListener <T> extends AnalysisEventListener<T> {
|
|||
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 <T> extends AnalysisEventListener<T> {
|
|||
Collection<String> 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 <T> extends AnalysisEventListener<T> {
|
|||
}
|
||||
|
||||
|
||||
public List<ExcelErrData<T>> getErrList() {
|
||||
return errList;
|
||||
public List<ExcelErrData<T>> getAndClearErrList() {
|
||||
List<ExcelErrData<T>> tmp = this.errList;
|
||||
this.errList = new ArrayList<>();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
}
|
|
@ -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<TestCaseExcelData> {
|
||||
|
||||
@Resource
|
||||
private TestCaseService testCaseService;
|
||||
|
||||
private String projectId;
|
||||
|
@ -26,13 +30,13 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
|
||||
Set<String> userIds;
|
||||
|
||||
public TestCaseDataListener(TestCaseService testCaseService, String projectId,
|
||||
Set<String> testCaseNames, Set<String> userIds, Class<TestCaseExcelData> clazz) {
|
||||
super(clazz);
|
||||
this.testCaseService = testCaseService;
|
||||
public TestCaseDataListener() {}
|
||||
|
||||
public TestCaseDataListener init(String projectId, Set<String> testCaseNames, Set<String> userIds) {
|
||||
this.projectId = projectId;
|
||||
this.testCaseNames = testCaseNames;
|
||||
this.userIds = userIds;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,21 +47,22 @@ public class TestCaseDataListener extends EasyExcelListener<TestCaseExcelData> {
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -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 <T> String validateEntity(T obj) throws NoSuchFieldException {
|
||||
public <T> String validateEntity(T obj) throws NoSuchFieldException {
|
||||
StringBuilder result = new StringBuilder();
|
||||
Set<ConstraintViolation<T>> set = validator.validate(obj, Default.class);
|
||||
Set<ConstraintViolation<T>> set = localValidatorFactoryBean.getValidator().validate(obj, Default.class);
|
||||
if (set != null && !set.isEmpty()) {
|
||||
for (ConstraintViolation<T> 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();
|
||||
|
|
|
@ -60,6 +60,9 @@ public class TestCaseService {
|
|||
@Resource
|
||||
TestCaseNodeService testCaseNodeService;
|
||||
|
||||
@Resource
|
||||
TestCaseDataListener testCaseDataListener;
|
||||
|
||||
@Resource
|
||||
UserMapper userMapper;
|
||||
|
||||
|
@ -187,11 +190,10 @@ public class TestCaseService {
|
|||
List<User> users = userMapper.selectByExample(userExample);
|
||||
Set<String> 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<ExcelErrData<TestCaseExcelData>> errList = easyExcelListener.getErrList();
|
||||
List<ExcelErrData<TestCaseExcelData>> errList = testCaseDataListener.getAndClearErrList();
|
||||
//如果包含错误信息就导出错误信息
|
||||
if (!errList.isEmpty()) {
|
||||
excelResponse.setSuccess(false);
|
||||
|
|
|
@ -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=
|
||||
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=
|
|
@ -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
|
||||
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
|
|
@ -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
|
Loading…
Reference in New Issue