2017-09-06 38 views
0

我正在爲移動應用程序編寫服務器端REST應用程序。我一直在試圖建立後面的解釋here,在那裏,而不是顯示一些HTTP錯誤頁,客戶端會收到類似這樣的一個JSON對象的異常處理程序:在Spring REST控制器中實現最佳實踐錯誤消息

{ 
    "status": 404, 
    "code": 40483, 
    "message": "Oops! It looks like that file does not exist.", 
    "developerMessage": "File resource for path /uploads/foobar.txt does not exist. Please wait 10 minutes until the upload batch completes before checking again.", 
    "moreInfo": "http://www.mycompany.com/errors/40483" 
} 

我已經仿照我的例外,這些詳細在指南中,他們似乎運作良好(自定義錯誤顯示在控制檯中)。但是我卡在this點,因爲我不知道我應該把bean配置放在哪裏。

鑑於我有我所有的異常處理程序,解析器等,我想我會嘗試以不同的方式解決它。在這一點上,當我輸入一個無效的HTTP請求時,我仍然會得到Spring的Whitelabel錯誤頁面,但是這次是我的例外情況下的自定義錯誤消息。所以我想,如果我試圖實現我自己的ErrorHandler如解釋here,我可能能夠使用Gson或其他東西構建JSON對象,而不是以前的文章去討論它。

我試圖得到最低限度ErrorHandler工作:

package com.myapp.controllers; 

import org.springframework.boot.autoconfigure.web.ErrorController; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RestController; 

import javax.servlet.http.HttpServletRequest; 

@RestController 
public class ErrorMessageController implements ErrorController { 

    private static final String ERROR_PATH = "/error"; 

    @Override 
    public String getErrorPath(){ 
     return ERROR_PATH; 
    } 

    @RequestMapping(value = ERROR_PATH) 
    public String renderErrorPage(HttpServletRequest request){ 

     String errorPage = (String) request.getAttribute("javax.servlet.error.status_code"); 

     return errorPage; 
    } 

} 

所以我希望得到的東西一樣出現在網頁上的孤404。而是我得到一個Tomcat錯誤頁面:

Tomcat Error Page

這是爲什麼?我會很感激任何幫助。

回答

2

發生這種情況是因爲request.getAttribute("javax.servlet.error.status_code")應該是Integer,並且您將其轉換爲String。這會在錯誤處理期間導致錯誤,從而彈出默認的Tomcat錯誤處理程序。

如果你將它轉換爲int,它將工作:

@RequestMapping(value = ERROR_PATH) 
public int renderErrorPage(HttpServletRequest request){ 

    int errorPage = (int) request.getAttribute("javax.servlet.error.status_code"); 

    return errorPage; 
} 

或者,如果你只是想返回特定的JSON結構,可以在實現一個ErrorController代替使用@ExceptionHandler方法。

例如,假設您有以下控制器:

@GetMapping 
public String getFoo() throws FileNotFoundException { 
    throw new FileNotFoundException("File resource for path /uploads/foobar.txt does not exist"); 
} 

如果要處理所有FileNotFoundExceptions以一種特殊的方式,你可以寫一個方法與@ExceptionHandler註釋:

@ExceptionHandler(FileNotFoundException.class) 
@ResponseStatus(HttpStatus.NOT_FOUND) 
public ErrorResponse notFound(FileNotFoundException ex) { 
    return new ErrorResponse(HttpStatus.NOT_FOUND.value(), 40483, "Oops! It looks like that file does not exist.", ex.getMessage(), "http://www.mycompany.com/errors/40483"); 
} 

在這種情況下,ErrorResponse是包含所需字段的POJO。如果你想爲所有的控制器重新使用它,你可以把它放在@ControllerAdvice

+0

那麼我在哪裏放置'@ ExceptionHandler'方法?在新的RestController中? –

+1

你可以選擇它。如果它只適用於單個控制器,則可以將該方法放在同一個控制器類中。如果它適用於所有控制器,那麼您創建一個新的簡單類,只需用'@ ControllerAdvice'註釋它,而不用其他任何東西。 – g00glen00b