在使用mvc编程方式下,全局异常拦截可使用如下方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* @author 小五
*/
@Slf4j
@RestControllerAdvice
@RequiredArgsConstructor
public class DefaultExceptionHandlerConfig {

@ExceptionHandler(BeHappyException.class)
//@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity beHappyExceptionHandler(BeHappyException e){
log.error("BeHappy Exception: {}",e.getMsg());
return ResponseEntity.internalServerError().body(e);
}
}

在使用路由式编程方式下,全局异常拦截可以使用如下方式(上面的方式对路由式不起作用)

  • GlobalErrorAttributes

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /**
    * @author 小五
    */
    @Slf4j
    @Component
    @RequiredArgsConstructor
    public class GlobalErrorAttributes extends DefaultErrorAttributes {

    final ObjectMapper objectMapper;

    @SneakyThrows
    @Override
    public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
    Map<String, Object> map = super.getErrorAttributes(request, ErrorAttributeOptions.defaults());
    if (getError(request) instanceof BeHappyException) {
    BeHappyException ex = (BeHappyException) getError(request);
    map.put("status", ex.getCode());
    map.put("error", ex.getMsg());
    }
    log.error(objectMapper.writeValueAsString(map));
    return map;
    }
    }
  • GlobalErrorWebExceptionHandler

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    /**
    * @author 小五
    */
    @Component
    @Order(-2)
    public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

    public GlobalErrorWebExceptionHandler(GlobalErrorAttributes g, ApplicationContext applicationContext,
    ServerCodecConfigurer serverCodecConfigurer) {
    super(g, new WebProperties.Resources(), applicationContext);
    super.setMessageWriters(serverCodecConfigurer.getWriters());
    super.setMessageReaders(serverCodecConfigurer.getReaders());
    }

    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(final ErrorAttributes errorAttributes) {
    return RouterFunctions.route(RequestPredicates.all(), serverRequest -> {
    final Map<String, Object> errorPropertiesMap = getErrorAttributes(serverRequest, ErrorAttributeOptions.defaults());

    return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR)
    .contentType(MediaType.APPLICATION_JSON)
    .body(BodyInserters.fromValue(errorPropertiesMap));
    });
    }
    }
  • BeHappyException

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    @ToString
    @Builder
    public class BeHappyException extends ResponseStatusException {

    @Setter
    @Getter
    private int code;

    @Setter
    @Getter
    private String msg;

    public BeHappyException(int code, String msg) {
    super(HttpStatus.INTERNAL_SERVER_ERROR,msg);
    this.code = code;
    this.msg = msg;
    }
    }
  • 测试

    1
    2
    3
    4
    5
    6
    7
    8
    //GET("/test4/{name}",accept(MediaType.APPLICATION_JSON), testHnadler::test4)
    public Mono<ServerResponse> test4(ServerRequest serverRequest) {
    if (serverRequest.pathVariable("name").equals("1")){
    return Mono.error(BeHappyException.builder().code(BizEnum.PREPAYMENT_EXCEPTION.getCode()).msg(BizEnum.PREPAYMENT_EXCEPTION.getMsg()).build());
    }else {
    return Mono.error(new RuntimeException("test error"));
    }
    }
  • 得到结果如下

    1
    2
    3
    4
    5
    6
    7
    {
    "timestamp": "2021-09-25T07:26:01.401+00:00",
    "path": "/test4/1",
    "status": 12002,
    "error": "支付验证失败,请重新发起支付",
    "requestId": "e002c2cd-1"
    }