2017-06-05 142 views
2

我在Spring Boot 1.5.3中有一個特殊的情況,在@ControllerAdvice中註釋了ExceptionHandler。它捕獲任何異常的默認異常,但如果我拋出一個自定義異常,它不會觸發。Spring Boot @ControllerAdvice部分工作,不適用於自定義異常

的的ExceptionHandler:

@ControllerAdvice 
public class ResponseEntityExceptionHandler { 

@ExceptionHandler({ HttpMessageNotReadableException.class }) 
protected ResponseEntity<ErrorModel> handleInvalidJson(RuntimeException e, WebRequest request) { 
    return new ResponseEntity<ErrorModel>(new ErrorModel().message("Could not parse JSON."), HttpStatus.BAD_REQUEST); 
} 

@ExceptionHandler({ NumberFormatException.class }) 
protected ResponseEntity<ErrorModel> handleInvalidRequest(RuntimeException e, WebRequest request) { 
    return new ResponseEntity<ErrorModel>(new ErrorModel().message("Invalid request parameter."), HttpStatus.BAD_REQUEST); 
} 

@ExceptionHandler({ CannotCreateTransactionException.class }) 
protected ResponseEntity<ErrorModel> handleTransactionCreationException(RuntimeException e, WebRequest request) { 
    return new ResponseEntity<ErrorModel>(new ErrorModel().message("Error connecting to the database, please make sure it is still available."), HttpStatus.BAD_REQUEST); 
} 

@ExceptionHandler({ NotFoundException.class }) 
protected ResponseEntity<ErrorModel> handleApiException(RuntimeException e, WebRequest request) { 
    return new ResponseEntity<ErrorModel>(new ErrorModel().message(e.getMessage()), HttpStatus.NOT_FOUND); 
} 
} 

前3例外都得到捕獲和處理,因爲他們應該,但底部異常得到由默認的彈簧引導的ExceptionHandler處理。這是一個自定義異常,我拋出一個控制器內:

public ResponseEntity<?> deleteActor(@ApiParam(value = "Used to identify a single actor.", required = true) @PathVariable("actor_id") Integer actorId, @RequestHeader("Accept") String accept) throws Exception { 
Actor actor = actorRepository.findOne(actorId); 
if (actor == null) { 
    throw new NotFoundException(404, "Not found"); 
} 
actorRepository.delete(actorId); 
return new ResponseEntity<Void>(HttpStatus.NO_CONTENT); 
} 

我試着拋頂例外像這樣的一個:

public ResponseEntity<?> readActor(@ApiParam(value = "Used to identify a single actor.", required = true) @PathVariable("actor_id") Integer actorId, @RequestHeader("Accept") String accept) throws Exception { 
    Actor actor = actorRepository.findOne(actorId); 
    if (actor == null) { 
     throw new NumberFormatException(""); 
    } 
    return new ResponseEntity<Actor>(actor, HttpStatus.OK); 
} 

而這些得到處理就好了...

將tomcat日誌也顯示此:

2017-06-05 11:30:20.080 INFO 9076 --- [   main] .m.m.a.ExceptionHandlerExceptionResolver : Detected @ExceptionHandler methods in responseEntityExceptionHandler 

除外:

public class NotFoundException extends ApiException { 
private int code; 
public NotFoundException (int code, String msg) { 
    super(code, msg); 
    this.code = code; 
} 
} 

例外從這個基類繼承:

public class ApiException extends Exception{ 
private int code; 
public ApiException (int code, String msg) { 
    super(msg); 
    this.code = code; 
} 
} 

爲什麼自定義異常由的ExceptionHandler避免檢測任何想法?

如果有必要,我很樂意提供更多信息。

回答

1

對於這種特殊情況,答案是使用Exception而不是RuntimeException,因爲NotFoundException只會從Exception繼承。

另外值得注意的事項:

  • 捕獲所有異常可以如果使用通用名例外,經常檢查是否已導入正確的使用@ExceptionHandler(Exception.class)

+0

我添加了您的建議,由於某種原因,這會捕獲前3個例外,但不是底部的例外。讓一個函數捕獲所有異常也不是期望的行爲。我寧願現在趕上特定的,所以我可以返回自定義錯誤消息。 – user6058309

+0

檢查並導入正確的NotFoundException:/,我也嘗試拋出並捕獲更一般的ApiException,但沒有成功。 – user6058309

+0

OK,我的最後一次嘗試將使用異常,而不是RuntimeException的在handleApiException: 保護ResponseEntity handleApiException(例外五,WebRequest的請求){ 返回新ResponseEntity (新ErrorModel()消息(e.getMessage())。 ,HttpStatus.NOT_FOUND); – rainerhahnekamp

相關問題