RequestMapping 转换异常

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

我有一个 Spring RequestMapping,它采用 JSON 结构并将其转换为 POJO。如果我向路由发送格式错误的 JSON 结构,我会收到“400 错误请求”,但我希望收到一条错误消息,说明为什么这是错误请求。我有一个验证器也检查 JSON 结构,但如果结构无法转换,它似乎不会被调用。有没有办法可以访问内置的 HttpMessageConverter 错误或异常?

spring spring-mvc
3个回答
1
投票

我认为您可以通过重写 handleHttpMessageNotReadable 方法来使用

ResponseEntityExceptionHandler
来实现此目的。

来自:17.11.3 处理标准 Spring MVC 异常

如果您更喜欢通过 @ExceptionHandler 方法编写错误内容,您可以扩展 ResponseEntityExceptionHandler 。这是 @ControllerAdvice 类的便捷基础,提供 @ExceptionHandler 方法来处理标准 Spring MVC 异常并返回 ResponseEntity。这允许您自定义响应并使用消息转换器编写错误内容。有关更多详细信息,请参阅 ResponseEntityExceptionHandler javadocs。

可以在此处找到

ResponseEntityExceptionHandler
的示例用法:http://www.jayway.com/2013/02/03/improve-your-spring-rest-api-part-iii/

否则你可以在这里找到更多 spring mvc 异常处理方法: https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

如果您的需求不太复杂,您可能只想使用 SimpleMappingExceptionResolver


1
投票

ResponseEntityExceptionHandler 用于识别 Spring MVC 特定异常并为它们实现常见的错误响应处理策略

它由许多方法组成,例如:

  1. handleMissingServletRequestParameter > 处理无效请求 params
  2. handleHttpMessageNotReadable > 处理无效请求 body
  3. handleExceptionInternal > 一个单一位置来自定义所有异常类型的响应正文。

下面提到的代码覆盖了 handleExceptionInternal 方法

@ControllerAdvice
public class JavaWebExeptionHandler extends ResponseEntityExceptionHandler {
    public class ExpnDetails {
        public int expnCode;
        public String expnMessage;
    }

    // A single place to customize the response body of all exception types.
    @Override
    protected ResponseEntity<ExpnDetails> handleExceptionInternal(Exception ex, Object body, 
                     HttpHeaders headers,HttpStatus status, WebRequest request) {
        return new ResponseEntity<Object>(new ExpnDetails(status.value(), ex.getMessage()), status);
    }
}

因此,所有 Spring MVC 特定异常都在一个地方处理,并且 ExpnDetails 对象作为响应 body 发送,其中包含 expnCode 和 expnMessage。

输出:

{
    "expnCode": 415,
    "expnMessage": "Content type 'application/json1' not supported"
}

{
    "expnCode": 400,
    "expnMessage": "JSON parse error: Unexpected character ('"
    ' (code 34)): was expecting comma to separate Object entries; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('
    "' (code 34)): was expecting comma to separate Object entries at [Source: (PushbackInputStream); line: 3, column: 4]"
}

注意此解决方案还有助于隐藏容器(例如tomcat服务器)详细信息,以便在请求失败时出现在响应错误中。


0
投票

如果您不想使用任何自定义类,而只想区分特定情况(例如无效的 json),您可以使用类似以下内容:

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers,
                                                              HttpStatusCode status, WebRequest request) {
    String defaultDetail = (ex.getMessage() != null && ex.getMessage().contains("JSON parse error"))
            ? "Invalid JSON Request"
            : "Failed to read request";
    ProblemDetail body = createProblemDetail(ex, status, defaultDetail, null, null, request);
    return handleExceptionInternal(ex, body, headers, status, request);
  }
}

这里我们使用与默认实现类似的实现,但只是将消息调整为特定于实际问题。您还可以直接使用 ex.getMessage 并传递它(如果您可以将整个详细信息公开给客户端),否则您可以构建自定义逻辑以按照上面所示的方式转换特定错误。

因此,在上面的代码中,如果由于 JSON 格式问题导致正文根本不可读,我们将得到正确的响应。

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