首页 文章

使用@ExceptionHandler根据请求动态返回HTTP状态代码

提问于
浏览
1

我想根据响应对象错误动态返回HTTPStatus代码,如400,400,404等 . 我被提到这个问题 - Programmatically change http response status using spring 3 restful但它没有帮助 .

我有一个带有 @ExceptionHandler 方法的Controller类

@ExceptionHandler(CustomException.class)
    @ResponseBody
    public ResponseEntity<?> handleException(CustomException e) {
        return new ResponseEntity<MyErrorResponse>(
                new MyErrorResponse(e.getCode(), ExceptionUtility.getMessage(e.getMessage())), 
                ExceptionUtility.getHttpCode(e.getCode()));
    }

ExceptionUtility 是一个类,我有上面使用的两个方法( getMessagegetCode ) .

public class ExceptionUtility {
    public static String getMessage(String message) {
        return message;
    }

    public static HttpStatus getHttpCode(String code) {
        return HttpStatus.NOT_FOUND; //how to return status code dynamically here ?
    }
}

我不想检查条件并相应地返回响应代码,还有其他更好的方法吗?

2 回答

  • 0

    您需要为不同的Exception定义不同的Exception处理程序,然后使用 @ResponseStatus ,如下所示:

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
        @ExceptionHandler({ UnAuthorizedException.class })
        public @ResponseBody ExceptionResponse unAuthorizedRequestException(final Exception exception) {
    
            return response;
        }
    
    @ResponseStatus(HttpStatus.CONFLICT)
        @ExceptionHandler({ DuplicateDataException.class })
        public @ResponseBody ExceptionResponse DuplicateDataRequestException(final Exception exception) {
    
            return response;
        }
    
    @ResponseStatus(HttpStatus.BAD_REQUEST)
        @ExceptionHandler({ InvalidException.class })
        public @ResponseBody ExceptionResponse handleInvalidException(final Exception exception) {
    
            return response;
        }
    

    这里的例子是 InvalidException.classDuplicateDataException.class 等 . 您可以定义自定义异常并从控制器层抛出它们 . 例如,您可以定义 UserAlreadyExistsException 并从异常处理程序返回 HttpStatus.CONFLICT 错误代码 .

  • 0

    您的 @ExceptionHandler 方法需要两件事:(i)有一个 HttpServletResponse 参数,以便您可以设置响应状态代码; (ii)没有 @ResponseStatus 注释 .

    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public ResponseEntity<?> handleException(HttpServletResponse resp, CustomException e) {
        resp.setStatus(ExceptionUtility.getHttpCode(e.getCode()).value());
        return new ResponseEntity<MyErrorResponse>(
                new MyErrorResponse(e.getCode(), ExceptionUtility.getMessage(e.getMessage())),
                ExceptionUtility.getHttpCode(e.getCode()));
    }
    

    我已经使用这种 @ExceptionHandler 来处理 NestedServletException ,这是一个例外,Spring有时会创建它来包装需要处理的"actual"异常(下面的代码) . 请注意,如果需要, @ExceptionHandler 方法可以同时将请求和响应对象作为参数 .

    @ExceptionHandler(NestedServletException.class)
    @ResponseBody
    public Object handleNestedServletException(HttpServletRequest req, HttpServletResponse resp, 
            NestedServletException ex) {
        Throwable cause = ex.getCause();
        if (cause instanceof MyBusinessLogicException) {
            resp.setStatus(HttpStatus.UNPROCESSABLE_ENTITY.value());
            return createStructureForMyBusinessLogicException((MyBusinessLogicException) cause);
        }
        if (cause instanceof AuthenticationException) {
            resp.setStatus(HttpStatus.UNAUTHORIZED.value());
        } else if (cause instanceof AccessDeniedException) {
            resp.setStatus(HttpStatus.FORBIDDEN.value());
        } else {
            resp.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
        return createStructureForOtherErrors(req, cause.getMessage(), resp.getStatus());
    }
    

相关问题