Java 如何为不同类型的异常设置不同的状态代码

Java 如何为不同类型的异常设置不同的状态代码,java,spring,spring-boot,exception-handling,Java,Spring,Spring Boot,Exception Handling,我正在尝试使用@ControllerAdvice处理spring启动应用程序中的异常。我不想为每种类型的异常使用单独的方法。我只想使用一个方法处理所有类型的异常,主类为@ExceptionHandler(exception.class) 我试着像下面一样正确地处理异常,但问题是,我还想为不同类型的异常设置不同类型的状态代码 这里我得到了每种类型的异常的500 有人能告诉我如何为不同类型的异常设置不同的状态代码吗 @ControllerAdvice public class Res

我正在尝试使用
@ControllerAdvice
处理spring启动应用程序中的异常。我不想为每种类型的异常使用单独的方法。我只想使用一个方法处理所有类型的异常,主类为
@ExceptionHandler(exception.class)

我试着像下面一样正确地处理异常,但问题是,我还想为不同类型的异常设置不同类型的状态代码

这里我得到了每种类型的异常的
500

有人能告诉我如何为不同类型的异常设置不同的状态代码吗

    @ControllerAdvice
    public class RestExceptionHandler {

        @ExceptionHandler(Exception.class)
        public  ResponseEntity<Object>  handleAllExceptionMethod(Exception ex,WebRequest requset) {

            ExceptionMessage exceptionMessageObj = new ExceptionMessage();                                   

            exceptionMessageObj.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            exceptionMessageObj.setMessage(ex.getLocalizedMessage());
            exceptionMessageObj.setError(ex.getClass().getCanonicalName());     
            exceptionMessageObj.setPath(((ServletWebRequest) requset).getRequest().getServletPath());

            return new ResponseEntity<>(exceptionMessageObj, new HttpHeaders(),HttpStatus.INTERNAL_SERVER_ERROR);       
        }
    }
@ControllerAdvice
公共类RestExceptionHandler{
@ExceptionHandler(Exception.class)
公共响应handleAllExceptionMethod(异常示例,WebRequest请求){
ExceptionMessageExceptionMessageObj=新的ExceptionMessage();
exceptionMessageObj.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
exceptionMessageObj.setMessage(例如getLocalizedMessage());
exceptionMessageObj.setError(例如getClass().getCanonicalName());
exceptionMessageObj.setPath(((ServletWebRequest)requset).getRequest().getServletPath());
返回新的ResponseEntity(exceptionMessageObj,new HttpHeaders(),HttpStatus.INTERNAL_SERVER_ERROR);
}
}

您可以检查您的例外情况,并相应返回:

@ControllerAdvice
public class RestExceptionHandler {

 @ExceptionHandler(Exception.class)
 public ResponseEntity < Object > handleAllExceptionMethod(Exception ex, WebRequest requset) {

  if (ex instanceof MyCustomException1) {
   // Return error code 500
  } else {
   // return error code 404
  }
 }
@ControllerAdvice
公共类RestExceptionHandler{
@ExceptionHandler(Exception.class)
公共响应属性handleAllExceptionMethod(异常示例,WebRequest请求){
如果(例如MyCustomException1的实例){
//返回错误代码500
}否则{
//返回错误代码404
}
}

您可以检查您的例外情况,并相应返回:

@ControllerAdvice
public class RestExceptionHandler {

 @ExceptionHandler(Exception.class)
 public ResponseEntity < Object > handleAllExceptionMethod(Exception ex, WebRequest requset) {

  if (ex instanceof MyCustomException1) {
   // Return error code 500
  } else {
   // return error code 404
  }
 }
@ControllerAdvice
公共类RestExceptionHandler{
@ExceptionHandler(Exception.class)
公共响应属性handleAllExceptionMethod(异常示例,WebRequest请求){
如果(例如MyCustomException1的实例){
//返回错误代码500
}否则{
//返回错误代码404
}
}

您可以根据异常类型设置不同的状态代码

HttpStatus statuscode = HttpStatus.INTERNAL_SERVER_ERROR;

if(ex instanceof ExceptionClass1){
   statuscode = HttpStatus.BAD_REQUEST;
}else if(ex instanceof ExceptionClass2){
  statuscode = HttpStatus.FORBIDDEN;
}

您可以根据异常类型设置不同的状态代码

HttpStatus statuscode = HttpStatus.INTERNAL_SERVER_ERROR;

if(ex instanceof ExceptionClass1){
   statuscode = HttpStatus.BAD_REQUEST;
}else if(ex instanceof ExceptionClass2){
  statuscode = HttpStatus.FORBIDDEN;
}

您也可以使用另一种Spring方法。请注意,它不适用于本机Java异常(因为您需要向异常类定义添加注释),这可能是您可以接受的,也可能是您无法接受的

  • 为要显示的状态代码定义自定义异常(或重用当前业务逻辑中的现有异常)
  • 添加到每个异常的顶部
  • 在控制器中,仅抛出这些异常
  • 这样,您就不需要对异常进行任何类型检查。您甚至不需要定义自己的
    @ControllerAdvice
    。Spring将处理正确的HTTP状态代码。如果您选择仍然使用此方法实现
    @ControllerAdvice
    ,则可以使用注释获取正确的状态代码与:

    import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation
    
    HttpStatus resolveAnnotatedResponseStatus(Exception exception) {
        ResponseStatus annotation = findMergedAnnotation(exception.getClass(), ResponseStatus.class);
        if (annotation != null) {
            return annotation.value();
        }
        return HttpStatus.INTERNAL_SERVER_ERROR;
    }
    

    (最初发布的注释解析方法)

    您也可以使用不同的Spring方法。请注意,它不适用于本机Java异常(因为您需要将注释添加到异常类定义中),您可能会接受,也可能不会接受

  • 为要显示的状态代码定义自定义异常(或重用当前业务逻辑中的现有异常)
  • 添加到每个异常的顶部
  • 在控制器中,仅抛出这些异常
  • 这样,您就不需要对异常进行任何类型检查。您甚至不需要定义自己的
    @ControllerAdvice
    。Spring将处理正确的HTTP状态代码。如果您选择仍然使用此方法实现
    @ControllerAdvice
    ,则可以使用注释获取正确的状态代码与:

    import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation
    
    HttpStatus resolveAnnotatedResponseStatus(Exception exception) {
        ResponseStatus annotation = findMergedAnnotation(exception.getClass(), ResponseStatus.class);
        if (annotation != null) {
            return annotation.value();
        }
        return HttpStatus.INTERNAL_SERVER_ERROR;
    }
    
    (最初发布的注释解析方法)

    @ControllerAdvice
    公共类RestExceptionHandler{
    @ExceptionHandler(Exception.class)
    公共责任处理例外(例外e){
    log.error(“IOException:+e.getMessage());
    最终映射消息=新HashMap();
    message.put(“message”,“出错了…”);
    //我的自定义IOException处理程序:)
    if(IOException的实例){
    返回ResponseEntity.unprocessableEntity().body(消息);
    }
    返回新的响应状态(HttpStatus.NOT_IMPLEMENTED);
    }
    }
    
    @ControllerAdvice
    公共类RestExceptionHandler{
    @ExceptionHandler(Exception.class)
    公共责任处理例外(例外e){
    log.error(“IOException:+e.getMessage());
    最终映射消息=新HashMap();
    message.put(“message”,“出错了…”);
    //我的自定义IOException处理程序:)
    if(IOException的实例){
    返回ResponseEntity.unprocessableEntity().body(消息);
    }
    返回新的响应状态(HttpStatus.NOT_IMPLEMENTED);
    }
    }
    
    您可以使用switch语句创建多个案例:

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> exceptionHandler(Exception ex) {
        ErrorResponse errorResponse = new ErrorResponse(new DescriptionInErrorResponse());
        errorResponse.getError().setText(ex.getMessage());
    
        HttpStatus httpStatus = HttpStatus.UNPROCESSABLE_ENTITY;
    
        if (ex instanceof CustomException) {
            switch (((CustomException) ex).getCode()) {
                case BAD_REQUEST:
                    errorResponse.getError().setCode(ErrorCode.BAD_REQUEST.getName());
                    httpStatus = HttpStatus.BAD_REQUEST;
                    break;
                case NOT_FOUND:
                    errorResponse.getError().setCode(ErrorCode.NOT_FOUND.getName());
                    httpStatus = HttpStatus.NOT_FOUND;
                    break;
                case METHOD_ARGUMENT_NOT_VALID:
                    errorResponse.getError().setCode(ErrorCode.METHOD_ARGUMENT_NOT_VALID.getName());
                    httpStatus = HttpStatus.BAD_REQUEST;
                    break;
    
                default:
                    errorResponse.getError().setCode(ErrorCode.UNKNOWN.getName());
                    httpStatus = HttpStatus.UNPROCESSABLE_ENTITY;
                    break;
            }
        } else if (ex instanceof ConstraintViolationException
                || ex instanceof javax.validation.ConstraintViolationException) {
            errorResponse.getError().setCode(ErrorCode.BAD_REQUEST.getName());
            httpStatus = HttpStatus.BAD_REQUEST;
        } else if (ex instanceof MethodArgumentNotValidException) {
            errorResponse.getError().setCode(ErrorCode.METHOD_ARGUMENT_NOT_VALID.getName());
            httpStatus = HttpStatus.BAD_REQUEST;
    
        } else if (ex instanceof DataIntegrityViolationException) {
            errorResponse.getError().setCode(ErrorCode.INTERNAL_SERVER_ERROR.getName());
            httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
        } else if (ex instanceof HttpMessageNotReadableException) {
            errorResponse.getError().setCode(ErrorCode.BAD_REQUEST.getName());
            httpStatus = HttpStatus.BAD_REQUEST;
        } else if (ex instanceof ServletRequestBindingException){
            errorResponse.getError().setCode(ErrorCode.BAD_REQUEST.getName());
            httpStatus = HttpStatus.BAD_REQUEST;
        }
        else {
    
            log.error(ex.getMessage(), ex);
            errorResponse.getError().setCode(ErrorCode.INTERNAL_SERVER_ERROR.getName());
            httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
        }
    
        return ResponseEntity.status(httpStatus).body(errorResponse);
    }
    
    @ExceptionHandler(Exception.class)
    公共响应异常处理程序(异常处理程序){
    ErrorResponse ErrorResponse=新的ErrorResponse(新的DescriptionInErrorResponse());
    errorResponse.getError().setText(例如getMessage());
    HttpStatus HttpStatus=HttpStatus.UNPROCESSABLE_实体;
    如果(例如CustomException的实例){
    开关(((CustomException)ex).getCode()){
    案例错误请求:
    errorResponse.getError().setCode(ErrorCode.BAD_REQUEST.getName());
    httpStatus=httpStatus.BAD\u请求;
    打破
    未找到案例:
    错误响应