[英]Spring Boot custom exception within an Rest Service
我在基於Spring Boot的Rest服務中定義了一個全局異常處理:
@ControllerAdvice
public class GlobalExceptionController {
private final Logger LOG = LoggerFactory.getLogger(getClass());
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason = "Internal application error")
@ExceptionHandler({ServiceException.class})
@ResponseBody
public ServiceException serviceError(ServiceException e) {
LOG.error("{}: {}", e.getErrorCode(), e.getMessage());
return e;
}
}
和自定義ServiceException:
public class ServiceException extends RuntimeException {
private static final long serialVersionUID = -6502596312985405760L;
private String errorCode;
public ServiceException(String message, String errorCode, Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
}
// other constructors, getter and setters omitted
}
到目前為止一切都那么好,當一個異常被觸發時,控制器按預期工作並響應:
{
"timestamp": 1413883870237,
"status": 500,
"error": "Internal Server Error",
"exception": "org.example.ServiceException",
"message": "somthing goes wrong",
"path": "/index"
}
但是字段errorCode未顯示在JSON響應中。
那么如何在我的應用程序中定義自定義異常響應。
Spring Boot使用ErrorAttributes
的實現來填充呈現為JSON的Map
。 默認情況下,使用DefaultErrorAttributes
的實例。 要包含自定義errorCode
您需要提供一個自定義ErrorAttributes
實現,該實現了解ServiceException
及其錯誤代碼。 此自定義實現應該是配置中的@Bean
。
一種方法是子類DefaultErrorAttributes
:
@Bean
public ErrorAttributes errorAttributes() {
return new DefaultErrorAttributes() {
@Override
public Map<String, Object> getErrorAttributes(
RequestAttributes requestAttributes,
boolean includeStackTrace) {
Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);
Throwable error = getError(requestAttributes);
if (error instanceof ServiceException) {
errorAttributes.put("errorCode", ((ServiceException)error).getErrorCode());
}
return errorAttributes;
}
};
}
@Alex您可以使用注釋@ExceptionHandler(YourExceptionClass.class)來處理特定RestController中的特定異常。 我認為這是處理業務應用程序中復雜場景的更好方法。 此外,我建議您使用自定義異常轉換器來處理不同類型的異常。 您可以將spring oauth2異常轉換程序視為異常轉換程序的參考代碼。
注意:以下代碼僅用於理解此解決方案的概念。 它不是生產就緒代碼。 隨意討論更多相關信息。
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
/**
* @author Harpreet
* @since 16-Aug-17.
*/
@RestController
public class RestTestController {
@RequestMapping(value = "name", method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseObject name(@RequestParam(value="name") String value){
//your custom logic
if (value == null || value.length() < 2) {
//throwing exception to invoke customExceptionHandler
throw new NullPointerException("value of request_param:name is invalid");
}
ResponseObject responseObject = new ResponseObject();
responseObject.setMessage(value)
.setErrorCode(1);
return responseObject;
}
// to handle null pointer exception
@ExceptionHandler(NullPointerException.class)
public ResponseObject customExceptionHandler
(NullPointerException e) {
ResponseObject responseObject = new ResponseObject();
responseObject.setMessage(e.getMessage())
.setErrorCode(-1);
return responseObject;
}
// response data transfer class
static class ResponseObject{
String message;
Integer errorCode;
public String getMessage() {
return message;
}
public ResponseObject setMessage(String message) {
this.message = message;
return this;
}
public Integer getErrorCode() {
return errorCode;
}
public ResponseObject setErrorCode(Integer errorCode) {
this.errorCode = errorCode;
return this;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.