2017-06-05 59 views
4

我想在我的Rest spring引導應用程序中處理異常。我知道用@ControllerAdvice和ResponseEntity我可以返回一個代表我的錯誤的自定義對象,但我想要的是向exesting異常的主體添加一個新字段。在body rest中添加新字段spring rest

我創建了一個自定義異常繼承RuntimeException的一個額外的屬性,字符串列表:

@ResponseStatus(HttpStatus.CONFLICT) 
public class CustomException extends RuntimeException { 

    private List<String> errors = new ArrayList<>(); 

    public CustomException(List<String> errors) { 
     this.errors = errors; 
    } 

    public CustomException(String message) { 
     super(message); 
    } 

    public CustomException(String message, List<String> errors) { 
     super(message); 
     this.errors = errors; 
    } 

    public List<String> getErrors() { 
     return errors; 
    } 

    public void setErrors(List<String> errors) { 
     this.errors = errors; 
    } 
} 

在我的控制器我只是把這個自定義異常這樣:

@GetMapping("/appointment") 
public List<Appointment> getAppointments() { 
    List<String> errors = new ArrayList<>(); 
    errors.add("Custom message"); 
    throw new CustomException("This is my message", errors); 
} 

當我測試我的休息端點郵遞員,好像春天開機不馬歇爾我的錯誤領域,迴應是:

{ 
    "timestamp": "2017-06-05T18:19:03", 
    "status": 409, 
    "error": "Conflict", 
    "exception": "com.htech.bimaristan.utils.CustomException", 
    "message": "This is my message", 
    "path": "/api/agenda/appointment" 
} 

如果我可以從異常中獲取「路徑」和「時間戳」字段,但是沒有獲取這兩個屬性的getters,我可以使用@ControllerAdvice來定製對象。

謝謝。

回答

3

好吧!這裏是DefaultErrorAttributes你能做到這一點在你的自定義實現過 「路徑」 和 「時間戳」 的實施:

路徑:

String path = getAttribute(requestAttributes, "javax.servlet.error.request_uri"); 
if (path != null) { 
    errorAttributes.put("path", path); 
} 

時間戳:

errorAttributes.put("timestamp", new Date()); 

有關彈簧啓動錯誤定製的文檔是here

@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); 
      // customize here 
      return errorAttributes; 
     } 

    }; 
} 

或者你可以寫一個自定義的實現:

@Component 
public class CustomErrorAttributes extends DefaultErrorAttributes { 

    @Override 
    public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) { 
     Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace); 
     // customize here 
     return errorAttributes; 
    } 
} 

ErrorAttributes豆定製以下錯誤響應:

{ 
    "timestamp": 1413883870237, 
    "status": 500, 
    "error": "Internal Server Error", 
    "exception": "org.example.ServiceException", 
    "message": "somthing goes wrong", 
    "path": "/index" 
} 

"exception"屬性可以使用@ExceptionHandler進行定製。 A @ControlerAdvice可以用於在控制器間定製異常。要在控制器級別進行定製,您可以將它們放置在控制器內。

你的情況:

@ResponseStatus(value=HttpStatus.BAD_REQUEST, reason="Invalid Inputs") 
    @ExceptionHandler(CustomException.class) 
    private void errorHanlder() { 
     //Log exception 
    } 


    public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) { 
    Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace); 
    Throwable error = getError(requestAttributes); 
    if (error instanceof CustomException) { 
     errorAttributes.put("errorList", ((CustomException)error).getErrors()); 
    } 
    return errorAttributes; 
} 
+1

我想這個功能在我的控制器整合,但我我做了我的端點調用每次得到這個異常: org.thymeleaf.exceptions.TemplateInputException:錯誤解析模板「通用/錯誤」,模板可能不存在或可能無法被配置的任何模板解析器訪問 – Habchi

+1

我認爲您正在實現REST端點。所以,使用ResponseEntity。 – YuVi

+1

這個解決方案就是我在問題中提到的。我可以使用它,但是如何從異常體中獲取路徑和時間戳屬性,以便我可以將它們添加到自定義錯誤對象? – Habchi