jisti-meet服务开启
This commit is contained in:
@@ -33,6 +33,11 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
|
||||
@@ -2,8 +2,11 @@ package org.xyzh.common.exception.handler;
|
||||
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.authorization.AuthorizationDeniedException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
@@ -26,17 +29,16 @@ import java.util.stream.Collectors;
|
||||
* @copyright yslg
|
||||
* @since 2025-12-17
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||
/**
|
||||
* 业务异常
|
||||
*/
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public ResultDomain<?> handleBusinessException(BusinessException e) {
|
||||
log.warn("业务异常: {}", e.getMessage());
|
||||
logger.warn("业务异常: {}", e.getMessage());
|
||||
return ResultDomain.failure(e.getCode(), e.getMessage());
|
||||
}
|
||||
|
||||
@@ -49,7 +51,7 @@ public class GlobalExceptionHandler {
|
||||
String message = e.getBindingResult().getFieldErrors().stream()
|
||||
.map(FieldError::getDefaultMessage)
|
||||
.collect(Collectors.joining("; "));
|
||||
log.warn("参数校验失败: {}", message);
|
||||
logger.warn("参数校验失败: {}", message);
|
||||
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), message);
|
||||
}
|
||||
|
||||
@@ -63,7 +65,7 @@ public class GlobalExceptionHandler {
|
||||
String message = violations.stream()
|
||||
.map(ConstraintViolation::getMessage)
|
||||
.collect(Collectors.joining("; "));
|
||||
log.warn("参数校验失败: {}", message);
|
||||
logger.warn("参数校验失败: {}", message);
|
||||
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), message);
|
||||
}
|
||||
|
||||
@@ -76,7 +78,7 @@ public class GlobalExceptionHandler {
|
||||
String message = e.getFieldErrors().stream()
|
||||
.map(FieldError::getDefaultMessage)
|
||||
.collect(Collectors.joining("; "));
|
||||
log.warn("参数绑定失败: {}", message);
|
||||
logger.warn("参数绑定失败: {}", message);
|
||||
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), message);
|
||||
}
|
||||
|
||||
@@ -87,7 +89,7 @@ public class GlobalExceptionHandler {
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public ResultDomain<?> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
|
||||
String message = "缺少必要参数: " + e.getParameterName();
|
||||
log.warn(message);
|
||||
logger.warn(message);
|
||||
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), message);
|
||||
}
|
||||
|
||||
@@ -98,7 +100,7 @@ public class GlobalExceptionHandler {
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public ResultDomain<?> handleMissingServletRequestPartException(MissingServletRequestPartException e) {
|
||||
String message = "缺少必要参数: " + e.getRequestPartName();
|
||||
log.warn(message);
|
||||
logger.warn(message);
|
||||
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), message);
|
||||
}
|
||||
|
||||
@@ -108,17 +110,27 @@ public class GlobalExceptionHandler {
|
||||
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public ResultDomain<?> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
|
||||
log.warn("文件上传大小超限: {}", e.getMessage());
|
||||
logger.warn("文件上传大小超限: {}", e.getMessage());
|
||||
return ResultDomain.failure(HttpStatus.BAD_REQUEST.value(), "上传文件大小超过限制");
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限不足异常
|
||||
*/
|
||||
@ExceptionHandler(AuthorizationDeniedException.class)
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public ResultDomain<?> handleAuthorizationDeniedException(AuthorizationDeniedException e) {
|
||||
logger.warn("权限不足: {}", e.getMessage());
|
||||
return ResultDomain.failure(HttpStatus.FORBIDDEN.value(), "权限不足");
|
||||
}
|
||||
|
||||
/**
|
||||
* 其他未捕获异常
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public ResultDomain<?> handleException(Exception e) {
|
||||
log.error("系统异常: ", e);
|
||||
logger.error("系统异常: ", e);
|
||||
return ResultDomain.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统异常,请联系管理员");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.xyzh.common.utils.validation;
|
||||
|
||||
import org.xyzh.common.utils.validation.method.FieldCompareValidateMethod;
|
||||
import org.xyzh.common.utils.validation.method.InSetValidateMethod;
|
||||
import org.xyzh.common.utils.validation.method.MinFieldsValidateMethod;
|
||||
import org.xyzh.common.utils.validation.method.ObjectValidateMethod;
|
||||
@@ -10,6 +11,7 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -380,4 +382,32 @@ public class ValidationUtils {
|
||||
.validateMethod(new InSetValidateMethod(fieldLabel, allowedValues))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 创建字段比较校验参数(比较对象中的两个字段)
|
||||
* @param field1Name 第一个字段名称
|
||||
* @param field2Name 第二个字段名称
|
||||
* @param fieldLabel 字段标签
|
||||
* @param compareFunction 比较函数:(field1Value, field2Value) -> Boolean,返回true表示通过
|
||||
* @param errorMessage 自定义错误消息
|
||||
* @return ValidationParam
|
||||
*/
|
||||
public static ValidationParam fieldCompare(String field1Name,
|
||||
String field2Name,
|
||||
String fieldLabel,
|
||||
BiFunction<Object, Object, Boolean> compareFunction,
|
||||
String errorMessage) {
|
||||
return ValidationParam.builder()
|
||||
.fieldName(field1Name)
|
||||
.fieldLabel(fieldLabel)
|
||||
.required(false)
|
||||
.validateMethod(new FieldCompareValidateMethod(
|
||||
field1Name,
|
||||
field2Name,
|
||||
fieldLabel,
|
||||
compareFunction,
|
||||
errorMessage
|
||||
))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
package org.xyzh.common.utils.validation.method;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* @description 字段比较校验方法,用于比较对象中的两个字段
|
||||
* @filename FieldCompareValidateMethod.java
|
||||
* @author Claude Code
|
||||
* @copyright xyzh
|
||||
* @since 2025-12-26
|
||||
*/
|
||||
public class FieldCompareValidateMethod implements ObjectValidateMethod {
|
||||
|
||||
/**
|
||||
* 第一个字段名称
|
||||
*/
|
||||
private final String field1Name;
|
||||
|
||||
/**
|
||||
* 第二个字段名称
|
||||
*/
|
||||
private final String field2Name;
|
||||
|
||||
/**
|
||||
* 字段标签(用于错误消息)
|
||||
*/
|
||||
private final String fieldLabel;
|
||||
|
||||
/**
|
||||
* 比较函数:(field1Value, field2Value) -> Boolean
|
||||
* 返回 true 表示校验通过,false 表示校验失败
|
||||
*/
|
||||
private final BiFunction<Object, Object, Boolean> compareFunction;
|
||||
|
||||
/**
|
||||
* 自定义错误消息
|
||||
*/
|
||||
private final String customErrorMessage;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @param field1Name 第一个字段名称
|
||||
* @param field2Name 第二个字段名称
|
||||
* @param fieldLabel 字段标签
|
||||
* @param compareFunction 比较函数
|
||||
* @param customErrorMessage 自定义错误消息
|
||||
*/
|
||||
public FieldCompareValidateMethod(String field1Name,
|
||||
String field2Name,
|
||||
String fieldLabel,
|
||||
BiFunction<Object, Object, Boolean> compareFunction,
|
||||
String customErrorMessage) {
|
||||
this.field1Name = field1Name;
|
||||
this.field2Name = field2Name;
|
||||
this.fieldLabel = fieldLabel;
|
||||
this.compareFunction = compareFunction;
|
||||
this.customErrorMessage = customErrorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean validate(Object targetObject) {
|
||||
if (targetObject == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取第一个字段的值
|
||||
Object field1Value = getFieldValue(targetObject, field1Name);
|
||||
|
||||
// 获取第二个字段的值
|
||||
Object field2Value = getFieldValue(targetObject, field2Name);
|
||||
|
||||
// 如果任意字段为null,跳过校验
|
||||
if (field1Value == null || field2Value == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 执行比较函数
|
||||
return compareFunction.apply(field1Value, field2Value);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("字段比较校验失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage() {
|
||||
if (customErrorMessage != null && !customErrorMessage.trim().isEmpty()) {
|
||||
return customErrorMessage;
|
||||
}
|
||||
return fieldLabel + "校验失败";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "字段比较校验";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段值(支持嵌套字段)
|
||||
*
|
||||
* @param obj 对象
|
||||
* @param fieldName 字段名称(支持 "field" 或 "nested.field")
|
||||
* @return 字段值
|
||||
*/
|
||||
private Object getFieldValue(Object obj, String fieldName) throws Exception {
|
||||
if (fieldName == null || fieldName.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 支持嵌套字段访问(如 "user.name")
|
||||
String[] fieldParts = fieldName.split("\\.");
|
||||
Object currentObj = obj;
|
||||
|
||||
for (String part : fieldParts) {
|
||||
if (currentObj == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取字段
|
||||
Field field = findField(currentObj.getClass(), part);
|
||||
if (field == null) {
|
||||
throw new NoSuchFieldException("字段不存在: " + part);
|
||||
}
|
||||
|
||||
// 设置可访问
|
||||
field.setAccessible(true);
|
||||
|
||||
// 获取字段值
|
||||
currentObj = field.get(currentObj);
|
||||
}
|
||||
|
||||
return currentObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找字段(包括父类)
|
||||
*
|
||||
* @param clazz 类
|
||||
* @param fieldName 字段名称
|
||||
* @return 字段
|
||||
*/
|
||||
private Field findField(Class<?> clazz, String fieldName) {
|
||||
Class<?> currentClass = clazz;
|
||||
while (currentClass != null) {
|
||||
try {
|
||||
return currentClass.getDeclaredField(fieldName);
|
||||
} catch (NoSuchFieldException e) {
|
||||
currentClass = currentClass.getSuperclass();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user