Files
xuan-deduct/src/main/java/xuan/exception/GlobalExceptionHandler.java
T
H1d3rOne 04e858f6cf 后端API全面优化:添加参数验证、全局异常处理和金币增减方法
问题修复:
1. 参数验证问题
   - 创建DTO类:UpdateVipRequest、UpdateCoinsRequest、UpdatePhoneRequest
   - 使用@NotBlank、@NotNull、@Min、@Max、@Pattern注解验证参数
   - 防止NullPointerException和非法参数

2. 全局异常处理
   - 创建GlobalExceptionHandler全局异常处理器
   - 统一处理Exception、MethodArgumentNotValidException等异常
   - 返回友好的错误信息,避免暴露敏感信息
   - 添加日志记录

3. 统一响应格式
   - 创建ApiResponse统一响应类
   - 包含success、data、error、code、timestamp字段
   - 提供success()和error()静态方法

4. 金币增减方法
   - UserInfoService新增addCoins方法(增加金币)
   - UserInfoService新增deductCoins方法(扣除金币)
   - 添加参数验证和余额检查
   - 金币不足时抛出IllegalArgumentException

技术实现:
- 使用Spring @RestControllerAdvice实现全局异常处理
- 使用javax.validation注解进行参数验证
- 使用SLF4J记录日志
- 统一HTTP状态码和业务错误码
2026-03-09 16:00:58 +08:00

63 lines
2.6 KiB
Java

package xuan.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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 xuan.common.ApiResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResponse<?>> handleException(Exception e) {
logger.error("系统异常", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error("系统繁忙,请稍后重试"));
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ApiResponse<?>> handleValidation(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getFieldErrors().stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
logger.warn("参数验证失败: {}", message);
return ResponseEntity.badRequest()
.body(ApiResponse.error(message, 400));
}
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<ApiResponse<?>> handleConstraintViolation(ConstraintViolationException e) {
String message = e.getConstraintViolations().stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.joining(", "));
logger.warn("参数验证失败: {}", message);
return ResponseEntity.badRequest()
.body(ApiResponse.error(message, 400));
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ApiResponse<?>> handleIllegalArgument(IllegalArgumentException e) {
logger.warn("参数错误: {}", e.getMessage());
return ResponseEntity.badRequest()
.body(ApiResponse.error(e.getMessage(), 400));
}
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<ApiResponse<?>> handleRuntimeException(RuntimeException e) {
logger.error("运行时异常", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiResponse.error("操作失败,请稍后重试"));
}
}