提交 306e3449 编写于 作者: C chenjianxing

JSR-303校验国际化

上级 64d6d11f
......@@ -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;
}
}
\ No newline at end of file
......@@ -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();
}
......
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=
\ 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
......@@ -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
......@@ -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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册