2015-04-17 60 views
4

我有一個彈簧引導應用程序。Spring Boot - 錯誤控制器來處理JSON或HTML

我有一個自定義錯誤控制器,它映射到使用ErrorPage映射。映射主要基於HTTP狀態代碼,通常只是適當地呈現HTML視圖。

例如,我的映射:

@Configuration 
class ErrorConfiguration implements EmbeddedServletContainerCustomizer { 

    @Override public void customize(ConfigurableEmbeddedServletContainer container) { 
     container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404.html")) 
    } 

我的差錯控制:

@Controller 
@RequestMapping 
public class ErrorController { 

    @RequestMapping(value = "/error/404.html") 
    @ResponseStatus(value = HttpStatus.NOT_FOUND) 
    public String pageNotFound(HttpServletRequest request) { 
     "errors/404" 
    } 

這工作正常 - 如果我只需要輸入一個隨機不存在的URL,然後它呈現404頁。

現在,我希望我的網站的一部分,可以說/api/..是獻給我的JSON API,以服務錯誤,JSON,所以如果我進入下/ API隨機不存在的URL/..然後返回404 JSON響應。

有沒有什麼標準/最好的方法來做到這一點?我試過的一個想法是有一個@ControllerAdvice,它專門捕獲了我定義並返回JSON的一類自定義API異常,並在我的標準ErrorController中檢查該URL,並在該API URL空間下拋出一個apprpriate API異常(但該didn不起作用,因爲ExceptionHandler方法不能被調用,因爲它是與原始控制器方法不同的返回類型)。

這個問題已經解決了嗎?

+0

你能否詳細說明你最後的陳述?目前還不清楚你的意思是不能被調用的,因爲它是不同的返回類型_。 – zeroflagL

+0

謝謝@zeroflagL - 我應該添加更多細節 - 我現在不在編碼,但是當我回來時會添加更多細節..這是我在測試時看到的更多觀察行爲,但並非詳盡無遺。可能性是由於拋出的代碼在ErrorController中(所以在Spring錯誤處理過程中已經存在),ControllerAdvice不起作用 – rhinds

回答

1

這個問題是我自己的錯。我試圖弄清楚爲什麼我的@ExceptionHandler無法捕捉到我的異常並返回JSON - 正如我在問題結束時所建議的那樣,我認爲由於衝突的返回類型,我遇到了問題 - 這是不正確的。

錯誤我正在試圖讓我異常處理程序返回JSON是沿着線:

"exception": "org.springframework.web.HttpMediaTypeNotAcceptableException", 
    "message": "Could not find acceptable representation" 

我做了一些更多的挖/試驗,以儘量縮小問題(認爲這個問題是因爲我在Spring錯誤處理流程中,並且在導致問題的ErrorController中),但是這個問題僅僅是因爲Spring所做的內容協商。

因爲我在web.xml中的errorPage映射映射到/error/404.html,Spring使用後綴來解析相應的視圖 - 所以當我試圖返回json時,它失敗了。

我已經能夠通過將我的web.xml更改爲/error/404或關閉內容協商後綴選項來解決此問題。

0

現在,我希望我的網站的一部分,讓我們說/ API/..這是專門 我的JSON API,以服務錯誤,JSON,所以如果我進入下一個隨機 不存在的URL/api/..然後它返回404 JSON響應。

有沒有什麼標準/最好的方法來做到這一點?我試過的一個想法是 有一個@ControllerAdvice,它專門捕獲了一類定製的 API異常,我定義並返回了JSON,並在我的標準 ErrorController中檢查URL並拋出API 異常,如果在該API URL空間(但不起作用,因爲 ExceptionHandler方法無法調用,因爲它是原始控制器方法的不同返回類型 )。

我認爲你需要重新思考你在這裏想要做什麼。根據HTTP響應代碼here

404或Not Found錯誤消息是指示客戶端能夠與給定 服務器進行通信,但服務器無法找到被請求的是什麼一個HTTP標準響應代碼 。

所以,當輸入一個隨機的網址,你可能不想總是拋出404。如果你正在嘗試處理錯誤請求你可以做這樣的事情

@ControllerAdvice 
public class GlobalExceptionHandlerController { 

    @ExceptionHandler(NoHandlerFoundException.class) 
    @ResponseStatus(value = HttpStatus.BAD_REQUEST) 
    @ResponseBody 
    public ResponseEntity<ErrorResponse> noRequestHandlerFoundExceptionHandler(NoHandlerFoundException e) { 
     log.debug("noRequestHandlerFound: stacktrace={}", ExceptionUtils.getStackTrace(e)); 

     String errorCode = "400 - Bad Request"; 
     String errorMsg = "Requested URL doesn't exist"; 

     return new ResponseEntity<>(new ErrorResponse(errorCode, errorMsg), HttpStatus.BAD_REQUEST); 
    } 
} 

構建ResponseEntity該套件您的需要。

+0

我很高興我應該使用404不存在的URL(同意如果它是無效的/語法上的非法的URL我會400)。 Spring MVC的默認行爲是404任何不匹配映射模式的請求(假設它匹配dispatcherservlet上下文)。例如,如果你嘗試在這裏輸入一個隨機URL:http://stackoverflow.com/aaaa/bbbbb它404s你。 – rhinds