在處理異常時,咱們須要對API請求拋出的異常時,咱們要以JSON的形式返回錯誤信息。而在請求頁面時報錯的話,咱們須要在跳轉到相應的報錯頁面進行友好提示。html
在進入全局異常處理器以前,加一個攔截器,在preHandle中取得HandlerMethod,判斷請求的Controller方法的返回類型,以及請求的Controller方法是否使用的@RestController
或者@ResponBody
註解。若知足以上條件則拋出異常時,應該返回json格式的報錯信息,不然返回相應的錯誤頁面。spring
/**
* 判斷Controller是返回json仍是頁面的攔截器,爲統一異常處理返回結果作判斷依據
*/
@Component
public class ExceptionPreHandleInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod hm = (HandlerMethod) handler;
Method method = hm.getMethod();
//Controller方法返回值是否爲字符串
boolean b1 = method.getReturnType().equals(String.class);
//Controller方法是否使用@ResponseBody註解
boolean b2 = !method.isAnnotationPresent(ResponseBody.class);
//Controller是否使用@RestController註解
boolean b3 = !hm.getBeanType().isAnnotationPresent(RestController.class);
request.setAttribute("method_return_is_view", b1 && b2 && b3);
return true;
}
}
複製代碼
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
ExceptionPreHandleInterceptor exceptionPreHandleInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 全局異常處理 前置處理攔截器
registry.addInterceptor(exceptionPreHandleInterceptor).addPathPatterns("/**");
}
}
複製代碼
@ControllerAdvice
public class BaseControllerAdvice {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@ExceptionHandler
public Object handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws Exception {
//獲取攔截器判斷的返回結果類型
Object o = request.getAttribute("method_return_is_view");
if (o == null) {
logger.error("", e);
throw e;
}
//是不是html/text
boolean isView = (Boolean) o;
//返回頁面
if (isView) {
ModelAndView modelAndView = new ModelAndView("/error");//配置須要跳轉的Controller方法
request.setAttribute("message", "系統異常");
return modelAndView;
} else {//返回json
ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
modelAndView.addObject("code", "500");
modelAndView.addObject("message", "系統異常");
modelAndView.addObject("data", );
return modelAndView;
}
}
}
複製代碼
原文地址: springboot全局異常處理ControllerAdvice示例區分方法返回類型json仍是頁面json