在自定义对象中包装默认REST错误响应

问题描述 投票:0回答:1

我正在构建一个简单的REST api用于集成目的,我希望响应尽可能一致(无论错误如何都一样)。

我过去使用过@ExceptionHandler方法 - 所以如果我没记错的话,我很可能会选择这个类的版本... @ControllerAdvice

我知道它有效,我之前用过SO来帮助我,它只需要设置。这不是我的问题......

API允许创建消息和搜索消息(两个单独的请求),因此,接受内部验证的日期值。经过测试,我收到了一个非常好的格式化和令人难以置信的详细错误响应:

{
    "timestamp": "2018-08-31T10:35:10.748+0000",
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            "codes": [
                "typeMismatch.IntegrationMessageFilter.fromDate",
                "typeMismatch.fromDate",
                "typeMismatch.java.util.Date",
                "typeMismatch"
            ],
            "arguments": [
                {
                    "codes": [
                        "IntegrationMessageFilter.fromDate",
                        "fromDate"
                    ],
                    "arguments": null,
                    "defaultMessage": "fromDate",
                    "code": "fromDate"
                }
            ],
            "defaultMessage": "Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'fromDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@com.fasterxml.jackson.annotation.JsonFormat java.util.Date] for value '213-456-45'; nested exception is java.lang.IllegalArgumentException",
            "objectName": "IntegrationMessageFilter",
            "field": "fromDate",
            "rejectedValue": "213-456-45",
            "bindingFailure": true,
            "code": "typeMismatch"
        }
    ],
    "message": "Validation failed for object='IntegrationMessageFilter'. Error count: 1",
    "path": "/Integration/get"
}

我想要做的是拦截这个错误并将其包装在我自己的响应对象中,该对象对于每个可用的API方法都是相同的响应对象:例如

{
    "success": Boolean,
    "messageId": Integer, (null on search, int on successful create)
    "messages": Array, (searched IntegrationMessage objects)
    "errorMessage": String, (error message during manual validation (e.g. range validation depending on the field))
    "error" [SPRING DEFAULT ERROR] (this is what i want to intercept from spring-boot and include in this response object)
}

当系统已经完成它时,手动提示有关创建详细错误消息的意义有点毫无意义...我不知道它用于创建上面的第一个JSON消息的对象,或者即使我可以拦截它。

注意:这纯粹是为了方便API用户不必区分不同的响应对象,以及方便我,而不必重新开发轮子(可以这么说)。

json rest spring-boot exception-handling
1个回答
0
投票

好的,所以我已经找到了如何实现(某种程度)我想要的东西。

我的印象是,我可以拦截完整的异常响应消息,并将其放在我的对象中,无论异常类型如何。事实证明,我可以获得大多数默认信息,但它特定于每种错误类型(显然)。

第一次尝试: 我的第一次尝试是使用以下内容简单地“测试”默认错误响应。这是为了确定春天正在做什么(它正在使用哪个错误 - 我认为它本来就是handleTypeMismatch例外) - 下面的方法只是类中的一个(我正在处理的那个):

@ControllerAdvice
public class IntegrationExceptionHandler extends ResponseEntityExceptionHandler
{
    @Override
    public ResponseEntity<Object> handleBindException(final BindException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request)
    {
        return super.handleBindException(ex, headers, status, request);
    }
}

我期望与默认错误消息完全相同的错误消息,但这没有产生响应(或空响应?)。

我的“解决方案”: 虽然我不需要重新开发轮子,但我必须做一些箍跳:

    @Override
    public ResponseEntity<Object> handleBindException(final BindException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request)
    {               

        IntegrationResponse response = new IntegrationResponse(ex.getMessage());
        response.setErrors(ex.getBindingResult().getAllErrors());

        return new ResponseEntity<Object>(response, headers, status);
    }

错误是private List<ObjectError> errors;org.springframework.validation.ObjectError

因此,我将不得不尝试复制ResponseEntityExceptionHandler中的每个可覆盖错误(这适用于我的情况)并稍微区别对待它,您现在可以看到为什么我只想包装现有的响应。

正如旁注,我确实尝试添加:private Object error;private BindingResult error;作为我的响应对象中的变量,但是两次尝试似乎都拒绝我的响应对象并显示JUST默认消息(好像没有控制器建议)没有提示为什么。

如果有人确实发现如何跳过ResponseEntityExceptionHandler步骤并只包装默认的异常响应对象,我将很乐意接受这个答案。

© www.soinside.com 2019 - 2024. All rights reserved.