石墨消解仪后端服务
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
3.2 KiB

  1. package com.iflytop.gd.common.handler;
  2. import com.iflytop.gd.common.exception.AppException;
  3. import com.iflytop.gd.common.result.Result;
  4. import com.iflytop.gd.common.result.ResultCode;
  5. import jakarta.servlet.http.HttpServletRequest;
  6. import jakarta.validation.ConstraintViolationException;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.validation.BindException;
  9. import org.springframework.web.HttpRequestMethodNotSupportedException;
  10. import org.springframework.web.bind.MethodArgumentNotValidException;
  11. import org.springframework.web.bind.annotation.ExceptionHandler;
  12. import org.springframework.web.bind.annotation.RestControllerAdvice;
  13. import java.util.stream.Collectors;
  14. @Slf4j
  15. @RestControllerAdvice
  16. public class GlobalExceptionHandler {
  17. @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
  18. public Result<?> handleMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpServletRequest request) {
  19. String method = request.getMethod();
  20. String uri = request.getRequestURI();
  21. String allowed = ex.getSupportedHttpMethods() != null
  22. ? ex.getSupportedHttpMethods().toString()
  23. : "[]";
  24. String msg = String.format(
  25. "请求方法 '%s' 不支持 (URL: %s)。支持的方法有:%s",
  26. method, uri, allowed);
  27. log.error(msg, ex);
  28. return Result.failed(ResultCode.METHOD_NOT_ALLOWED.getCode(), msg);
  29. }
  30. // 1) JSON Body 校验失败
  31. @ExceptionHandler(MethodArgumentNotValidException.class)
  32. public Result<?> handleBodyValid(MethodArgumentNotValidException ex) {
  33. String msg = ex.getBindingResult().getFieldErrors().stream()
  34. .map(f -> f.getField() + ": " + f.getDefaultMessage())
  35. .collect(Collectors.joining("; "));
  36. return Result.failed(ResultCode.INVALID_PARAMETER.getCode(), msg);
  37. }
  38. // 2) 方法级参数校验失败(PathVariable/RequestParam)
  39. @ExceptionHandler(ConstraintViolationException.class)
  40. public Result<?> handleParamValid(ConstraintViolationException ex) {
  41. String msg = ex.getConstraintViolations().stream()
  42. .map(v -> {
  43. String path = v.getPropertyPath().toString();
  44. String field = path.substring(path.lastIndexOf('.') + 1);
  45. return field + ": " + v.getMessage();
  46. })
  47. .collect(Collectors.joining("; "));
  48. return Result.failed(ResultCode.INVALID_PARAMETER.getCode(), msg);
  49. }
  50. // 3) 表单绑定失败
  51. @ExceptionHandler(BindException.class)
  52. public Result<?> handleBind(BindException ex) {
  53. String msg = ex.getFieldErrors().stream()
  54. .map(f -> f.getField() + ": " + f.getDefaultMessage())
  55. .collect(Collectors.joining("; "));
  56. return Result.failed(ResultCode.INVALID_PARAMETER.getCode(), msg);
  57. }
  58. @ExceptionHandler(Exception.class)
  59. public Result<?> handleException(Exception ex) {
  60. if (ex instanceof AppException ae) {
  61. log.warn("AppException:", ae);
  62. return Result.failed(ae.getResultCode());
  63. }
  64. log.error("Unhandled exception:", ex);
  65. return Result.failed(ResultCode.SYSTEM_ERROR.getCode(), ex.getMessage());
  66. }
  67. }