包含:

  1. 错误处理
  2. 通用校验
  3. Actuator
  4. Aspect

错误处理

参考解决方案:

  1. Zalando problem-spring-web
  2. A Guide to the Problem Spring Web Library
  3. Spring Error Handing
  4. Spring Error Responses
  5. RFC9457 - Problem Details for HTTP APIs

HopeExceptionHandler@ControllerAdvice

  1. 根据异常类寻找最合适的 Exception Handler
  2. 处理异常
  3. 添加异常头(HTTP)
  4. 打印异常
  5. 返回结果

内置错误处理

类名备注
AsyncRequestTimeoutExceptionHandlerAsyncRequestTimeoutException
BindExceptionHandlerBindingResult
ConstraintViolationExceptionHandlerConstraintViolationException
HopeErrorDetailExceptionHandlerHopeErrorDetailException
HttpMediaTypeExceptionHandlerHttpMediaTypeException
HttpMessageNotReadableExceptionHandlerHttpMessageNotReadableException
HttpMessageNotWritableExceptionHandlerHttpMessageNotWritableException
MissingRequestValueExceptionHandlerMissingRequestValueException
ObjectOptimisticLockingFailureApiExceptionHandlerObjectOptimisticLockingFailureException
ServerErrorExceptionHandlerServerErrorException
ServerWebInputExceptionHandlerServerWebInputException
SpringSecurityExceptionHandlerAccessDeniedException & UsernameNotFoundException & org.springframework.security.authentication.*
TypeMismatchExceptionHandlerTypeMismatchException

异常会被 Exception Handler 处理封装成 ServerErrorEnum 对象再返回给客户端。

错误码错误标题错误描述错误描述2
1003000001MISSING_REQUEST_PARAMETERMissing Request Parameter请求参数缺失
1003000011MISSING_PATH_VARIABLEMissing Path Variable缺失路径参数
1003000012MISSING_MATRIX_VARIABLEMissing MatrixVariable Exception缺失Matrix 参数
1003000013MISSING_REQUEST_COOKIEMissing RequestCookie Exception校验异常错误,缺乏相关的cookie
1003000014MISSING_REQUEST_HEADERMissing RequestHeader Exception校验异常错误,缺乏相关的header
1003000023HTTP_REQUEST_METHOD_NOT_SUPPORTEDHttp Request Method Not SupportedHttp 请求方式不对
1003000024HTTP_MEDIA_TYPE_NOT_SUPPORTEDHttp MediaType Not SupportedHttp 请求数据格式不支持
1003000025HTTP_MEDIA_TYPE_NOT_ACCEPTABLEHttp MediaType Not AcceptableHttp 请求数据格式不对
1003000036SERVLET_REQUEST_BINDINGRequest Binding Exception请求数据绑定错误, 数据校验问题
1003000037TYPE_MISMATCHType Mismatch校验异常错误
1003000038METHOD_ARGUMENT_NOT_VALIDMethod Argument Not Valid校验异常错误
1003000039CONSTRAINT_VIOLATIONConstraint Violation校验异常错误
1003000040SERVER_ERRORServer Error,Exposes extra information about a controller method that failed, or a controller method argument that could not be resolved.服务内部错误
1003000041BINDING_ERRORServer Error,Exposes extra information about a controller method that failed, or a controller method argument that could not be resolved.数据绑定错误
1003000051HTTP_MESSAGE_NOT_READABLEHttp Message Not ReadableHttp 输入无法读取
1003000052HTTP_MESSAGE_NOT_WRITABLEHttp Message Not WritableHttp 无法输出
1003000060MISSING_REQUEST_PARTMissing Servlet Request Part Exception, ‘multipart/form-data’ request上传请求校验失败
1003000061ASYNC_REQUEST_TIMEOUTAsync Request Timeout Exception异步请求超时
1003000101ORM_OBJECT_OPTIMISTIC_LOCKING_FAILUREException thrown on an optimistic locking violation for a mapped object.对象乐观锁错误
1003000501SECURITY_ACCESS_DENIEDAccess Denied访问拒绝
1003000502SECURITY_ACCOUNT_EXPIREDAccount Expired账户失效
1003000503SECURITY_AUTHENTICATION_CREDENTIALS_NOT_FOUNDAuthentication Credentials Not Found授权信息不匹配
1003000504SECURITY_AUTHENTICATION_SERVICEAuthentication Service授权服务异常
1003000505SECURITY_BAD_CREDENTIALSBad Credentials错误授权
1003000506SECURITY_USER_NOT_FOUNDUser Not Found用户不存在
1003000507SECURITY_INSUFFICIENT_AUTHENTICATIONInsufficient Authentication授权检验错误
1003000508SECURITY_LOCKEDAccount Locked账号锁定
1003000509SECURITY_DISABLEDAccount Disabled账号禁用
1003000510SECURITY_AUTHENTICATIONAuthentication Fail授权错误
1003000511SECURITY_ANONYMOUS_UN_CHANGEABLEAuthentication Try Update Anonymous properties更新匿名错误
1003000512SECURITY_JWT_EXPIREJWT ExpireJWT过期
1003000513SECURITY_JWT_UNSUPPORTEDJWT UnsupportedJWT不支持
1003000514SECURITY_JWT_MALFORMEDJWT MalformedJWT格式错误
1003000515SECURITY_JWT_SIGNATUREJWT SignatureJWT签名错误
1003000516SECURITY_JWT_GENERICJWT Generic ExceptionJWT一般错误

BindingResult

BindingResult 并非exception, 而她的实现类里面有: BindException & WebExchangeBindException 是参数绑定异常类;

根据字段绑定错误翻译成 BINDING_ERROR 类型错误。

ConstraintViolationException

校验异常, 翻译 ConstraintViolationCONSTRAINT_VIOLATION类型错误。

HopeErrorDetailException

HopeErrorDetailException 为内部通用异常类,包含:

  1. message
  2. cause
  3. hope.common.api.error.Error 列表

错误配置

配置路径:hope.error; 配置对象: HopeProblemProperties

配置备注
codesException to the code mapper Map<String, String>
logLevelLog 输出详细程度
errorCodeStrategy错误类名处理方式
httpStatusesclass to the http status mapping Map<String, HttpStatus>
searchSuperClassHierarchywhether to search super class in the hierarchy
addPathToErrorwhether to add the path to the error details
messages输出信息映射 Map<String, String>

LogLevel

配置备注
NO_LOGGING不打印log
MESSAGE_ONLY只包含 message
WITH_STACKTRACE整个堆栈

ErrorCodeStrategy

名称备注
FULL_QUALIFIED_NAMEhope.common.spring.problem.Example
ALL_CAPShope.common.spring.problem.Example-> EXAMPLE

通用校验

名称备注
@ChinaMobile中国手机号码验证
@Enums枚举列表验证

Actuator

HopeProjectInfoContributor 包含运行时上下文信息方便调试调用:

名称备注
domaindomain 信息
applicationapplication 名称
mainClass入口类
mainPackage主包
stubBuildTimestub编译时间
project主项目 Project信息
protoproto Project 信息

Project 包含:

  1. Artifact
  2. name
  3. description
  4. module

等信息

Aspect

AspectManager 主要针对对外服务切面的管理:组织运行时上下文 Aspect 织入,运行是如下:

public ResponseEntity<Result<String>> exampleSayHello() {
    final SimpleResultBuilder<String> builder = new SimpleResultBuilder<String>();

    try {
    	aspect().before("/demo-001/hello-world" );
    	_service.exampleSayHello(builder);
    	ResponseEntity<Result<String>> res = builder.done();
    	aspect().after("/demo-001/hello-world", res  );
    	return res;
    } catch (Throwable exception ) { 
    	logger.error("FAIL_ACTION METHOD:[exampleSayHello] PATH:[/demo-001/hello-world]",exception);
    	aspect().exception("/demo-001/hello-world", exception  );
    	throw exception;
    }
  }

  public AspectManager aspect() {
    return AspectManager.get();
  }

分页

PageRequestGuardian 分页参数校验保护, 防止设置太大 page size;

Refer

  1. Zalando problem-spring-web
  2. A Guide to the Problem Spring Web Library
  3. Spring Error Handing
  4. Spring Error Responses
  5. RFC9457 - Problem Details for HTTP APIs