自由的羽毛 发表于 2025-4-6 18:37:59

Java非常处理与全局非常处理全面指南

Java非常处理与全局非常处理全面指南

一、Java非常处理底子

1. 非常分类

Java中的非常分为两大类:


[*]Checked Exception(检查型非常):必须被捕获或声明抛出,如IOException、SQLException
[*]Unchecked Exception(非检查型非常):RuntimeException及其子类,如NullPointerException、ArrayIndexOutOfBoundsException
2. 基本非常处理语法

try {
    // 可能抛出异常的代码
} catch (SpecificException e) {
    // 处理特定异常
} catch (GeneralException e) {
    // 处理更一般的异常
} finally {
    // 无论是否发生异常都会执行的代码
}
3. 非常处理最佳实践


[*]不要忽略非常:空的catch块是"罪过"的
[*]优先处理最具体的非常
[*]合理使用finally开释资源
[*]思量使用try-with-resources(Java 7+)
[*]避免在finally块中使用return
二、Spring全局非常处理机制

1. @ControllerAdvice + @ExceptionHandler

@ControllerAdvice
public class GlobalExceptionHandler {
   
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex) {
      ErrorResponse error = new ErrorResponse(
            "SERVER_ERROR",
            "An unexpected error occurred",
            HttpStatus.INTERNAL_SERVER_ERROR.value()
      );
      return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
   
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleResourceNotFound(
      ResourceNotFoundException ex) {
      ErrorResponse error = new ErrorResponse(
            "NOT_FOUND",
            ex.getMessage(),
            HttpStatus.NOT_FOUND.value()
      );
      return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }
}
2. 自界说非常类

public class BusinessException extends RuntimeException {
    private String errorCode;
    private HttpStatus httpStatus;
   
    public BusinessException(String message, String errorCode, HttpStatus httpStatus) {
      super(message);
      this.errorCode = errorCode;
      this.httpStatus = httpStatus;
    }
   
    // getters
}
3. 统一响应格式

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ErrorResponse {
    private String errorCode;
    private String message;
    private int status;
    private long timestamp;
    private String path;
    private List<ValidationError> validationErrors;
   
    public ErrorResponse(String errorCode, String message, int status) {
      this.errorCode = errorCode;
      this.message = message;
      this.status = status;
      this.timestamp = System.currentTimeMillis();
    }
}

@Data
@AllArgsConstructor
public class ValidationError {
    private String field;
    private String message;
}
三、高级非常处理本领

1. 处理验证非常(Validation)

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationExceptions(
    MethodArgumentNotValidException ex) {
   
    List<ValidationError> errors = ex.getBindingResult()
      .getFieldErrors()
      .stream()
      .map(error -> new ValidationError(
            error.getField(),
            error.getDefaultMessage()))
      .collect(Collectors.toList());
   
    ErrorResponse error = new ErrorResponse(
      "VALIDATION_FAILED",
      "Validation failed for one or more fields",
      HttpStatus.BAD_REQUEST.value(),
      errors
    );
   
    return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
2. 国际化非常消息

@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusinessException(
    BusinessException ex,
    WebRequest request,
    Locale locale) {
   
    String message = messageSource.getMessage(
      ex.getMessageKey(),
      ex.getArgs(),
      locale);
   
    ErrorResponse error = new ErrorResponse(
      ex.getErrorCode(),
      message,
      ex.getHttpStatus().value()
    );
   
    return new ResponseEntity<>(error, ex.getHttpStatus());
}
3. 日记记录策略

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex, WebRequest request) {
    logger.error("Unexpected error occurred: {}", ex.getMessage(), ex);
   
    ErrorResponse error = new ErrorResponse(
      "SERVER_ERROR",
      "An unexpected error occurred",
      HttpStatus.INTERNAL_SERVER_ERROR.value(),
      request.getDescription(false)
    );
   
    return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
四、实战建议


[*] 分层非常处理:

[*]控制器层:处理HTTP干系非常
[*]服务层:处理业务逻辑非常
[*]数据访问层:处理数据干系非常

[*] 非常转换:将底层非常转换为上层业务非常
[*] 非常信息设计:

[*]包含充足的信息用于调试
[*]不袒露敏感信息
[*]提供明确的错误代码

[*] 监控与报警:对关键非常设置监控报警
[*] 文档化:为API消耗者提供清晰的错误代码和寄义文档
五、常见问题办理方案


[*]处理404错误:
@ControllerAdvice
public class CustomErrorController implements ErrorController {
   
    @RequestMapping("/error")
    public ResponseEntity<ErrorResponse> handleError(HttpServletRequest request) {
      Integer status = (Integer) request.getAttribute("javax.servlet.error.status_code");
      Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
      
      ErrorResponse error = new ErrorResponse(
            "NOT_FOUND",
            "Requested resource not found",
            status
      );
      
      return new ResponseEntity<>(error, HttpStatus.valueOf(status));
    }
}

[*]处理跨域非常:
@ExceptionHandler
public ResponseEntity<ErrorResponse> handleCorsException(CorsException ex) {
    ErrorResponse error = new ErrorResponse(
      "CORS_ERROR",
      ex.getMessage(),
      HttpStatus.FORBIDDEN.value()
    );
    return new ResponseEntity<>(error, HttpStatus.FORBIDDEN);
}

[*]处理文件上传大小限制非常:
@ExceptionHandler(MaxUploadSizeExceededException.class)
public ResponseEntity<ErrorResponse> handleMaxSizeException(
    MaxUploadSizeExceededException exc) {
   
    ErrorResponse error = new ErrorResponse(
      "FILE_TOO_LARGE",
      "File size exceeds the allowed limit",
      HttpStatus.BAD_REQUEST.value()
    );
   
    return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
六、总结

精良的非常处理是构建结实Java应用步伐的关键。通过合理使用Java原生非常机制和Spring的全局非常处理功能,可以:

[*]进步代码的结实性和可维护性
[*]提供一致的用户体验
[*]便于问题排查和调试
[*]实现更好的系统监控
记着:非常处理的目标不是消灭所有非常,而是以可控的方式处理非常,并提供有意义的反馈。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Java非常处理与全局非常处理全面指南