当前位置: 首页 > 知识库问答 >
问题:

Spring ControllerAdvice不处理来自静态方法的异常

裴泰平
2023-03-14

我有以下方法:

static <T extends Enum<T> & IEnum> T getEnumFromString(Class<T> c, String value) throws EnumException {
    T[] values = c.getEnumConstants();
    for (T v : values) {
        if (v.getStringValue().equals(value)) {
            return v;
        }
    }

    throw new EnumException(String.format("[%s] enum does not have value [%s]", c.getSimpleName(), value));
}

在序列化期间调用。

枚举异常扩展了异常

我的控制器方法:

public ResponseEntity<Transaction> validateTransaction(@RequestBody Transaction transaction){
   ...
}

事务类:

public class Transaction {

    private TransactionType transactionType;
    private String iban;
    private String cnp;
    private String name;
    private String description;
    private Float sum;

    public void setTransactionType(String transactionType) throws EnumException {
        this.transactionType = TransactionType.fromString(transactionType);
    }
    ...
}

在此setter中,引发枚举异常

在调试@ControlllerAdvie方法时,我看到它正在从响应EntityExceptionHandler类调用handleException(...)方法而不是我的方法

在抛出EnumException的情况下,我得到400状态代码和空响应正文。

public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler(EnumException.class)
public ResponseEntity<Object> handleIllegalArgumentException(Exception ex, WebRequest request) {
    String errorMessage = ex.getMessage();
    Map<String, Object> responseBody = buildResponseBody(HttpStatus.BAD_REQUEST, errorMessage);
    return handleExceptionInternal(ex, responseBody, new HttpHeaders(), HttpStatus.CONFLICT, request);
}
}

为什么不执行异常处理程序方法?

以下是日志:

POST "/transaction", parameters={}
2019-08-01 16:54:46.429 DEBUG 11349 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity<com.orange.validator.model.Transaction> com.orange.validator.controller.TransactionController.validateTransaction(com.orange.validator.model.Transaction)
2019-08-01 16:54:50.262 DEBUG 11349 --- [nio-8080-exec-2] .w.s.m.m.a.ServletInvocableHandlerMethod : Could not resolve parameter [0] in public org.springframework.http.ResponseEntity<com.orange.validator.model.Transaction> com.orange.validator.controller.TransactionController.validateTransaction(com.orange.validator.model.Transaction): JSON parse error: [TransactionType] enum does not have value [sdsds]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: [TransactionType] enum does not have value [sdsds]
 at [Source: (PushbackInputStream); line: 7, column: 21] (through reference chain: com.orange.validator.model.Transaction["transactionType"])
2019-08-01 16:54:50.272 DEBUG 11349 --- [nio-8080-exec-2] .m.m.a.ExceptionHandlerExceptionResolver : Using @ExceptionHandler public final org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) throws java.lang.Exception
2019-08-01 16:54:50.300 DEBUG 11349 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : No match for [*/*], supported: []
2019-08-01 16:54:50.305 DEBUG 11349 --- [nio-8080-exec-2] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: [TransactionType] enum does not have value [sdsds]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: [TransactionType] enum does not have value [sdsds]
 at [Source: (PushbackInputStream); line: 7, column: 21] (through reference chain: com.orange.validator.model.Transaction["transactionType"])]
2019-08-01 16:54:50.306 DEBUG 11349 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed 400 BAD_REQUEST

共有2个答案

卢伟志
2023-03-14

解决方案是重写handlehttpmessageontradable(…)方法。

@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    IllegalArgumentException exception = (IllegalArgumentException) ex.getMostSpecificCause();
    String errorMessage = exception.getMessage();
    Map<String, Object> responseBody = buildResponseBody(HttpStatus.BAD_REQUEST, errorMessage);
    return handleExceptionInternal(ex, responseBody, new HttpHeaders(), HttpStatus.CONFLICT, request);
}

为了获取错误消息,我正在将HttpMessageOradeableException转换为抛出的异常,并获取正确的错误消息

胥英奕
2023-03-14

使用@ResponseBody来

@ExceptionHandler(EnumException.class)
@ResponseBody
public ResponseEntity<Object> handleIllegalArgumentException(Exception ex, W...

或者试试这个

@ExceptionHandler({ Throwable.class })
    @ResponseBody
    public ResponseEntity<ErrorResponse> handleException(final Throwable e, final webrequest request) {
       String errorMessage = e.getMessage();
       Map<String, Object> responseBody = buildResponseBody(HttpStatus.BAD_REQUEST, errorMessage);
       return handleExceptionInternal(e, responseBody, new HttpHeaders(), HttpStatus.CONFLICT, request);
    }
 类似资料:
  • 我有一个这样的方法。 这里 我想将这个KException转换为MyException。有没有一个优雅的方法来做这件事?请帮帮忙。

  • 问题内容: 我有一个快速的问题。在静态关键字声明之后立即开始的代码块,那是什么类型的方法?我从未见过。如果有人能启发我,将不胜感激。谢谢。 问题答案: 这不是方法,而是类的静态Initializer块。您可以在Java Language Specification中 阅读有关它的更多信息。 加载该类后,其中的代码将执行一次。

  • 问题内容: 我正在尝试使用Java的类来运行大量具有固定数量线程的重量级任务。每个任务都有很多地方,在这些地方可能会由于异常而失败。 我已经继承了子类,并且重写了应该提供运行任务时遇到的任何未捕获异常的方法。但是,我似乎无法使其工作。 例如: 该程序的输出是“一切都很好-情况正常!” 即使唯一提交给线程池的Runnable引发异常。任何线索这里发生了什么? 谢谢! 问题答案: 提交Runnable

  • 嗨,我有以下型号。 场馆模型 调查模型 当我试图获得一个地点的调查,我得到以下错误。 非静态方法 App\Venues::survey() 不应静态调用,假设$this来自不兼容的上下文 我已经在 Laravel 5.1 中创建了与此相同的模型和关系,而没有此问题。我想知道我是否在 Laravel 5.2 中遗漏了某些内容。

  • 本文向大家介绍java synchronized同步静态方法和同步非静态方法的异同,包括了java synchronized同步静态方法和同步非静态方法的异同的使用技巧和注意事项,需要的朋友参考一下 java synchronized 详解 synchronized关键字有两种用法,一种是只用于方法的定义中,另外一种是synchronized块,我们不仅可以使用synchronized来同步一个对

  • 我最近对 PHP 5.4 进行了更新,但收到有关静态和非静态代码的错误。 这是错误: 这是第371行: 我希望有人能帮忙。