我通過Spring exception handling documentation去了,我沒把握好主意如何處理AJAX調用未處理產生的異常。頁和Ajax調用春季異常處理
什麼是處理這兩種頁面請求未處理的異常和AJAX調用未處理的異常在一個應用程序方便易方法?
這可能是一個問題,因爲全球性的異常處理程序也搭上Ajax調用,並與很多東西返回「專用錯誤頁面」,從而防止了Ajax錯誤回調帶來苗條的錯誤答覆。
我通過Spring exception handling documentation去了,我沒把握好主意如何處理AJAX調用未處理產生的異常。頁和Ajax調用春季異常處理
什麼是處理這兩種頁面請求未處理的異常和AJAX調用未處理的異常在一個應用程序方便易方法?
這可能是一個問題,因爲全球性的異常處理程序也搭上Ajax調用,並與很多東西返回「專用錯誤頁面」,從而防止了Ajax錯誤回調帶來苗條的錯誤答覆。
有休息控制器異常處理的方式有三種:
註釋與@ResponseStatus和適當的HTTP結果代碼的異常給定異常被拋出時,應當返還。
例如,如果PersonNotFoundExcepition被拋出,返回HTTP 404客戶端(未找到)
@ResponseStatus(HttpStatus.NOT_FOUND)
public class PersonNotFoundException { … }
另一種方法是在你的控制器@ExceptionHandler註釋的方法。在@ExceptionHandler註解的值中,您可以定義應該捕獲哪些異常。此外,您可以在同一個方法上添加@ResponseStatus註釋來定義應將哪個HTTP結果代碼返回給客戶端。
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler({PersonNotFoundException.class})
public void handlePersonNotFound() {
...
}
優選的方法:實施ResponseEntityExceptionHandler接口作爲@ControllerAdvice。通過這種方式,您可以將異常處理邏輯應用於具有集中異常處理的所有控制器您可以在教程here中閱讀更多內容。
@ControllerAdvice
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
...
@Override
protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
String unsupported = "Unsupported content type: " + ex.getContentType();
String supported = "Supported content types: " + MediaType.toString(ex.getSupportedMediaTypes());
ErrorMessage errorMessage = new ErrorMessage(unsupported, supported);
return new ResponseEntity(errorMessage, headers, status);
}
...
}
注意,你不應該對所有類型的異常返回通用500 - Internal server error
。一般而言,您希望針對客戶端錯誤具有400個範圍的結果 - 錯誤的請求。 500s的結果代碼範圍到服務器端的錯誤。此外,根據所發生的事情而不是僅僅400或500返回更具體的代碼會更好。
「@ ControllerAdvice」如何與「@ Controller」映射。控制器中的異常如何映射到異常? –
它由所有的控制器共享,它不是每個控制器,所以你可以有集中的異常處理。基於異常類型(輸入參數)將適當的方法稱爲自動檢測。 –
我接觸到解決方案時使用請求標頭在全局異常處理程序中拆分ajax調用和序號頁面請求。對於ajax無效的用戶輸入類型的異常和內部服務器錯誤,也有不同的錯誤響應。
...
public class Application extends SpringBootServletInitializer {
@Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
r.setDefaultErrorView("forward:/errorController");
return r;
}
@Controller
public class ErrorController {
public static final Logger LOG = Logger.getLogger(ErrorController.class);
@RequestMapping(value = "/errorController")
public ModelAndView handleError(HttpServletRequest request,
@RequestAttribute("exception") Throwable th) {
ModelAndView mv = null;
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
if (isBusinessException(th)) {
mv = new ModelAndView("appAjaxBadRequest");
mv.setStatus(BAD_REQUEST);
} else {
LOG.error("Internal server error while processing AJAX call.", th);
mv = new ModelAndView("appAjaxInternalServerError");
mv.setStatus(INTERNAL_SERVER_ERROR);
}
mv.addObject("message", getUserFriendlyErrorMessage(th).replaceAll("\r?\n", "<br/>"));
} else {
LOG.error("Cannot process http request.", th);
mv = new ModelAndView("appErrorPage");
mv.addObject("exeption", th);
}
return mv;
}
}
AJAX調用可以是一個REST調用,但我相信你的意思是頁面請求與AJAX請求。我不明白問題1.由於您知道如何編寫異常處理程序,因此我不確定問題2背後的意圖。 – zeroflagL