init: UserBaseService (backend + deploy + scripts)
ci-userbase-service / build-and-push (push) Successful in 40s
ci-userbase-service / build-and-push (push) Successful in 40s
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
package com.yunhai.userbase.common;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 全局异常处理器:仅处理「参数校验」类异常,把 Spring 默认抛出的冗长消息收敛成「一句话」返回,
|
||||
* 避免前端收到整段 Validation failed ... 堆栈文本。<br>
|
||||
* 返回 HTTP 200 + {@code {code:4, msg:..., data:null}} 结构(而非 HTTP 400),
|
||||
* 与前端 alova errorHandle 的约定一致:status!=200 会被当作网络错误,code=4 才走「参数错误」分支。<br>
|
||||
* 注意:本处理器【不】处理业务异常(如 {@code DException}),业务异常交由项目框架统一处理
|
||||
* (返回 code=5、msg=异常消息),此处若拦截会覆盖框架行为。
|
||||
*
|
||||
* @author chenx
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
/** 参数校验失败的业务码,前端按「参数错误」处理 */
|
||||
private static final int CODE_PARAM_ERROR = 4;
|
||||
|
||||
/** @RequestBody + @Validated/@Valid 失败:提取每个字段的 defaultMessage。 */
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public Map<String, Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex) {
|
||||
return paramError(fieldErrorsMessage(ex.getBindingResult().getFieldErrors()));
|
||||
}
|
||||
|
||||
/** 普通 Bean 参数(如 SortChildren/Move 的 @Validated 请求体对象)校验失败。 */
|
||||
@ExceptionHandler(BindException.class)
|
||||
public Map<String, Object> handleBind(BindException ex) {
|
||||
return paramError(fieldErrorsMessage(ex.getBindingResult().getFieldErrors()));
|
||||
}
|
||||
|
||||
/** 方法级约束(@PathVariable/@RequestParam 上的 @NotNull 等)校验失败。 */
|
||||
@ExceptionHandler(ConstraintViolationException.class)
|
||||
public Map<String, Object> handleConstraintViolation(ConstraintViolationException ex) {
|
||||
String msg = ex.getConstraintViolations().stream()
|
||||
.map(ConstraintViolation::getMessage)
|
||||
.collect(Collectors.joining(";"));
|
||||
return paramError(msg);
|
||||
}
|
||||
|
||||
private String fieldErrorsMessage(java.util.List<FieldError> fieldErrors) {
|
||||
if (fieldErrors == null || fieldErrors.isEmpty()) {
|
||||
return "参数校验失败";
|
||||
}
|
||||
return fieldErrors.stream()
|
||||
.map(FieldError::getDefaultMessage)
|
||||
.collect(Collectors.joining(";"));
|
||||
}
|
||||
|
||||
/** HTTP 200 + code/msg/data 结构体,前端根据 code 提示 msg */
|
||||
private Map<String, Object> paramError(String msg) {
|
||||
Map<String, Object> body = new LinkedHashMap<>();
|
||||
body.put("code", CODE_PARAM_ERROR);
|
||||
body.put("msg", msg);
|
||||
body.put("data", null);
|
||||
return body;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user