mirror of
https://codeup.aliyun.com/64f7d6b8ce01efaafef1e678/coal/coal.git
synced 2026-01-25 07:46:40 +08:00
添加异常信息支持
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -57,6 +57,12 @@
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>0.10.2</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>1.9.4</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -44,7 +44,9 @@ public class R<T> {
|
||||
public static <T> R<T> fail(String code, String msg) {
|
||||
return create(null, code, msg);
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(String code, String msg, T data) {
|
||||
return create(data, code, msg);
|
||||
}
|
||||
public static <T> R<T> create(T data, String code, String msg) {
|
||||
|
||||
return new R<>(data, code, msg);
|
||||
|
||||
@@ -11,6 +11,8 @@ import cn.lihongjie.coal.empSalaryItem.dto.UpdateEmpSalaryItemDto;
|
||||
import cn.lihongjie.coal.empSalaryItem.service.EmpSalaryItemService;
|
||||
import cn.lihongjie.coal.empSalaryItemConfig.service.EmpSalaryItemConfigService;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -34,7 +36,7 @@ public class EmpSalaryItemController {
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public EmpSalaryItemDto update(@RequestBody UpdateEmpSalaryItemDto request) {
|
||||
public EmpSalaryItemDto update(@Valid @RequestBody UpdateEmpSalaryItemDto request) {
|
||||
return this.service.update(request);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package cn.lihongjie.coal.empSalaryItem.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
import cn.lihongjie.coal.validator.RequireCode;
|
||||
import cn.lihongjie.coal.validator.RequireName;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@@ -8,6 +10,8 @@ import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.Formula;
|
||||
|
||||
@Data
|
||||
@RequireName
|
||||
@RequireCode
|
||||
public class UpdateEmpSalaryItemDto extends OrgCommonDto {
|
||||
|
||||
|
||||
|
||||
@@ -12,18 +12,28 @@ import cn.lihongjie.coal.errorMsg.entity.ErrorMsgEntity;
|
||||
import cn.lihongjie.coal.errorMsg.mapper.ErrorMsgMapper;
|
||||
import cn.lihongjie.coal.errorMsg.repository.ErrorMsgRepository;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional
|
||||
@@ -82,4 +92,56 @@ public class ErrorMsgService extends BaseService<ErrorMsgEntity, ErrorMsgReposit
|
||||
|
||||
return page.map(this.mapper::toDto);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void initDefault(){
|
||||
|
||||
ClassPathResource classPathResource = new ClassPathResource("/config/errorMsg.json");
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||||
|
||||
List<ErrorMsgEntity> errorMsgs;
|
||||
|
||||
List<ErrorMsgEntity> exists = findAll();
|
||||
|
||||
try (InputStream inputStream = classPathResource.getInputStream()) {
|
||||
errorMsgs =
|
||||
mapper.readValue(inputStream, new TypeReference<List<ErrorMsgEntity>>() {});
|
||||
}
|
||||
|
||||
for (ErrorMsgEntity defaultMsg : errorMsgs) {
|
||||
|
||||
boolean found = false;
|
||||
for (ErrorMsgEntity exist : exists) {
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(defaultMsg.getCode(), exist.getCode()) ){
|
||||
|
||||
|
||||
found = true;
|
||||
|
||||
if (!StringUtils.equals(defaultMsg.getMsg(), exist.getMsg())){
|
||||
exist.setMsg(defaultMsg.getMsg());
|
||||
this.repository.save(exist);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ErrorMsgEntity nd = new ErrorMsgEntity();
|
||||
nd.setCode(defaultMsg.getCode());
|
||||
nd.setName(defaultMsg.getName());
|
||||
nd.setMsg(defaultMsg.getMsg());
|
||||
|
||||
|
||||
|
||||
|
||||
this.repository.save(nd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import cn.lihongjie.coal.organization.dto.UpdateOrganizationDto;
|
||||
import cn.lihongjie.coal.organization.entity.OrganizationEntity;
|
||||
import cn.lihongjie.coal.organization.mapper.OrganizationMapper;
|
||||
import cn.lihongjie.coal.organization.repository.OrganizationRepository;
|
||||
import cn.lihongjie.coal.salaryItem.service.SalaryItemService;
|
||||
import cn.lihongjie.coal.user.dto.CreateOrgAdminDto;
|
||||
import cn.lihongjie.coal.user.service.UserService;
|
||||
|
||||
@@ -43,7 +42,6 @@ class OrganizationService extends BaseService<OrganizationEntity, OrganizationRe
|
||||
|
||||
@Autowired CoalParameterDefService coalParameterDefService;
|
||||
|
||||
@Autowired SalaryItemService salaryItemService;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {}
|
||||
@@ -60,7 +58,6 @@ class OrganizationService extends BaseService<OrganizationEntity, OrganizationRe
|
||||
dto.setPassword(request.getOrgAdminPassword());
|
||||
userService.createOrgAdmin(dto);
|
||||
coalParameterDefService.initDefault(entity.getId());
|
||||
salaryItemService.initOrgDefault(entity.getId());
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package cn.lihongjie.coal.runner;
|
||||
|
||||
import cn.lihongjie.coal.coalParameterDef.service.CoalParameterDefService;
|
||||
import cn.lihongjie.coal.dictionary.service.DictionaryService;
|
||||
import cn.lihongjie.coal.errorMsg.service.ErrorMsgService;
|
||||
import cn.lihongjie.coal.organization.entity.OrganizationEntity;
|
||||
import cn.lihongjie.coal.organization.service.OrganizationService;
|
||||
import cn.lihongjie.coal.passwordDict.service.PasswordDictService;
|
||||
@@ -50,6 +51,8 @@ public class InitDataRunner implements CommandLineRunner {
|
||||
|
||||
@Autowired PasswordDictService passwordDictService;
|
||||
|
||||
@Autowired ErrorMsgService errorMsgService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void run(String... args) throws Exception {
|
||||
@@ -79,6 +82,7 @@ public class InitDataRunner implements CommandLineRunner {
|
||||
|
||||
passwordDictService.initDict();
|
||||
|
||||
errorMsgService.initDefault();
|
||||
|
||||
} finally {
|
||||
SecurityContextHolder.clearContext();
|
||||
|
||||
@@ -4,19 +4,55 @@ import cn.lihongjie.coal.base.dto.R;
|
||||
import cn.lihongjie.coal.exception.BizException;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
@Order(1)
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public R handleException(
|
||||
MethodArgumentNotValidException ex, HttpServletRequest request, HandlerMethod handlerMethod) {
|
||||
logEx(ex, request, handlerMethod);
|
||||
List<ConstraintViolation> allError =
|
||||
ex.getBindingResult().getAllErrors().stream()
|
||||
.map(oe -> oe.unwrap(ConstraintViolation.class))
|
||||
.collect(Collectors.toList());
|
||||
List<Map<String, ? extends Object>> errorData =
|
||||
allError.stream()
|
||||
.map(
|
||||
x ->
|
||||
Map.of(
|
||||
"field",
|
||||
x.getPropertyPath() == null? "null" : x.getPropertyPath().toString(),
|
||||
"msg",
|
||||
x.getMessage(),
|
||||
|
||||
"annotation",
|
||||
x.getConstraintDescriptor()
|
||||
.getAnnotation() == null ? "null":x.getConstraintDescriptor()
|
||||
.getAnnotation()
|
||||
.annotationType()
|
||||
.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return R.fail("validError", errorData.stream().map(x -> x.get("msg") + "").collect(Collectors.joining(", ")), errorData);
|
||||
}
|
||||
|
||||
@ExceptionHandler(BizException.class)
|
||||
public R handleException(
|
||||
BizException ex, HttpServletRequest request, HandlerMethod handlerMethod) {
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package cn.lihongjie.coal.spring.config;
|
||||
|
||||
import cn.lihongjie.coal.errorMsg.service.ErrorMsgService;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.MessageSourceResolvable;
|
||||
import org.springframework.context.NoSuchMessageException;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
public class ValidatorConfig {
|
||||
|
||||
@Autowired private ErrorMsgService errorMsgService;
|
||||
|
||||
public MessageSource messageSource(){
|
||||
return new MessageSource() {
|
||||
@Override
|
||||
public String getMessage(
|
||||
String code, Object[] args, String defaultMessage, Locale locale) {
|
||||
|
||||
String message = errorMsgService.getMsg(code);
|
||||
|
||||
return StringUtils.firstNonBlank(message, defaultMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage(String code, Object[] args, Locale locale)
|
||||
throws NoSuchMessageException {
|
||||
return getMessage(
|
||||
code, args, getMessage("default.message", args, "", locale), locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage(MessageSourceResolvable resolvable, Locale locale)
|
||||
throws NoSuchMessageException {
|
||||
|
||||
String[] codes = resolvable.getCodes();
|
||||
for (String code : codes) {
|
||||
String message = getMessage(code, resolvable.getArguments(), "", locale);
|
||||
if (StringUtils.isNotBlank(message)) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
return resolvable.getDefaultMessage();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalValidatorFactoryBean validator() {
|
||||
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
|
||||
|
||||
bean.setValidationMessageSource(messageSource());
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
34
src/main/java/cn/lihongjie/coal/validator/Require.java
Normal file
34
src/main/java/cn/lihongjie/coal/validator/Require.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package cn.lihongjie.coal.validator;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
import jakarta.validation.Constraint;
|
||||
import jakarta.validation.Payload;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
|
||||
@Target({ TYPE, ANNOTATION_TYPE, TYPE_USE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Constraint(validatedBy = RequireValidator.class)
|
||||
@Documented
|
||||
@Repeatable(Require.List.class)
|
||||
public @interface Require {
|
||||
|
||||
String message() default "{require.default}";
|
||||
|
||||
|
||||
String field() ;
|
||||
|
||||
Class<?>[] groups() default { };
|
||||
|
||||
Class<? extends Payload>[] payload() default { };
|
||||
|
||||
|
||||
@Target({ TYPE, ANNOTATION_TYPE, TYPE_USE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@interface List {
|
||||
Require[] value();
|
||||
}
|
||||
}
|
||||
26
src/main/java/cn/lihongjie/coal/validator/RequireCode.java
Normal file
26
src/main/java/cn/lihongjie/coal/validator/RequireCode.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package cn.lihongjie.coal.validator;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import jakarta.validation.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
|
||||
@NotNull
|
||||
@Target({ TYPE, ANNOTATION_TYPE, TYPE_USE })
|
||||
@Require(field = "code")
|
||||
@Retention(RUNTIME)
|
||||
@Constraint(validatedBy = { })
|
||||
@Documented
|
||||
@ReportAsSingleViolation
|
||||
public @interface RequireCode {
|
||||
|
||||
String message() default "{require.code}";
|
||||
|
||||
Class<?>[] groups() default { };
|
||||
|
||||
Class<? extends Payload>[] payload() default { };
|
||||
}
|
||||
26
src/main/java/cn/lihongjie/coal/validator/RequireFiles.java
Normal file
26
src/main/java/cn/lihongjie/coal/validator/RequireFiles.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package cn.lihongjie.coal.validator;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import jakarta.validation.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
|
||||
@NotNull
|
||||
@Target({ TYPE, ANNOTATION_TYPE, TYPE_USE })
|
||||
@Require(field = "fileIds")
|
||||
@Retention(RUNTIME)
|
||||
@Constraint(validatedBy = { })
|
||||
@Documented
|
||||
@ReportAsSingleViolation
|
||||
public @interface RequireFiles {
|
||||
|
||||
String message() default "{require.fileIds}";
|
||||
|
||||
Class<?>[] groups() default { };
|
||||
|
||||
Class<? extends Payload>[] payload() default { };
|
||||
}
|
||||
27
src/main/java/cn/lihongjie/coal/validator/RequireName.java
Normal file
27
src/main/java/cn/lihongjie/coal/validator/RequireName.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package cn.lihongjie.coal.validator;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import jakarta.validation.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.util.*;
|
||||
|
||||
@NotNull
|
||||
@Target({ TYPE, ANNOTATION_TYPE, TYPE_USE })
|
||||
@Require(field = "name")
|
||||
@Retention(RUNTIME)
|
||||
@Constraint(validatedBy = { })
|
||||
@Documented
|
||||
@ReportAsSingleViolation
|
||||
public @interface RequireName {
|
||||
|
||||
String message() default "{require.name}";
|
||||
|
||||
Class<?>[] groups() default { };
|
||||
|
||||
Class<? extends Payload>[] payload() default { };
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.lihongjie.coal.validator;
|
||||
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import jakarta.validation.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
|
||||
@NotNull
|
||||
@Target({ TYPE, ANNOTATION_TYPE, TYPE_USE })
|
||||
@Require(field = "sortKey")
|
||||
@Retention(RUNTIME)
|
||||
@Constraint(validatedBy = { })
|
||||
@Documented
|
||||
@ReportAsSingleViolation
|
||||
public @interface RequireSortKey {
|
||||
|
||||
String message() default "{require.sortKey}";
|
||||
|
||||
Class<?>[] groups() default { };
|
||||
|
||||
Class<? extends Payload>[] payload() default { };
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package cn.lihongjie.coal.validator;
|
||||
|
||||
import jakarta.validation.ConstraintValidator;
|
||||
import jakarta.validation.ConstraintValidatorContext;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@Slf4j
|
||||
public class RequireValidator implements ConstraintValidator<Require, Object> {
|
||||
|
||||
private String field;
|
||||
|
||||
@Override
|
||||
public void initialize(Require constraintAnnotation) {
|
||||
|
||||
this.field = constraintAnnotation.field();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public boolean isValid(Object value, ConstraintValidatorContext context) {
|
||||
|
||||
|
||||
try {
|
||||
|
||||
Object fv = PropertyUtils.getProperty(value, field);
|
||||
|
||||
if (fv instanceof CharSequence s){
|
||||
return StringUtils.isNotBlank(s);
|
||||
}
|
||||
|
||||
return !ObjectUtils.isEmpty(fv) ;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("error", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
26
src/main/resources/config/errorMsg.json
Normal file
26
src/main/resources/config/errorMsg.json
Normal file
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"code": "success",
|
||||
"msg": "成功"
|
||||
},
|
||||
{
|
||||
"code": "require.default",
|
||||
"msg": "必填项未填写"
|
||||
},
|
||||
{
|
||||
"code": "require.name",
|
||||
"msg": "名称必填"
|
||||
},
|
||||
{
|
||||
"code": "require.code",
|
||||
"msg": "编码必填"
|
||||
},
|
||||
{
|
||||
"code": "require.sortKey",
|
||||
"msg": "排序字段必填"
|
||||
},
|
||||
{
|
||||
"code": "require.fileIds",
|
||||
"msg": "必须上传附件"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user