前因
博主在寫項目的時候,自定義了一個異常類,繼承自運行時異常類:
/**
* 禁止訪問異常類
* @author alageek
*/
public class AccessForbiddenException extends RuntimeException {
private static final long serialVersionUID = 7526324512252691698L;
public AccessForbiddenException(){
super();
}
public AccessForbiddenException(String message, Throwable cause, Boolean enableSuppression, Boolean writableStackTrace){
super(message, cause, enableSuppression, writableStackTrace);
}
public AccessForbiddenException(String message, Throwable cause){
super(message, cause);
}
public AccessForbiddenException(Throwable cause){
super(cause);
}
public AccessForbiddenException(String message){
super(message);
}
}
而後在攔截器中,將其拋出:
/**
* 登錄攔截
* @author alageek
*/
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Admin admin = (Admin) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN);
if(admin == null){
throw new AccessForbiddenException(CrowdConstant.MESSAGE_ACCESS_FORBIDDEN);
}
return true;
}
}
同時又在SpringMVC中設置了全局異常處理:
/**
* 異常處理機制
* @author alageek
* 註解ControllerAdvice表示當前類是基於註解的異常處理器類
*/
@ControllerAdvice
public class CrowdExceptionResolver {
/**
* 禁止訪問異常處理
* 註解ExceptionHandler將異常類與方法關聯
* @param exception 異常對象
* @param request 請求對象
* @param response 響應對象
* @return 若請求爲Ajax請求,則返回json類型的錯誤信息,否則返回錯誤頁面
* @throws IOException ResultEntity對象轉json異常
*/
@ExceptionHandler(value = AccessForbiddenException.class)
public ModelAndView resolveAccessForbiddenException(
AccessForbiddenException exception,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
String viewName = "admin-login";
return commonResolve(exception, request, response, viewName);
}
private ModelAndView commonResolve(
Exception exception,
HttpServletRequest request,
HttpServletResponse response,
String viewName) throws IOException {
if(CrowdUtil.judgeRequestType(request)){
// Ajax請求
response.getWriter().write(new Gson().toJson(ResultEntity.failed(exception.getMessage())));
return null;
}
// 普通請求
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION, exception);
modelAndView.setViewName(viewName);
return modelAndView;
}
}
最終的啓動項目後,發現在攔截器拋出AccessForbiddenException異常時,全局異常處理並未捕獲到異常。
BUG定位
經過百度SpringMVC全局異常處理的三種方式後,恍然大悟,按上面博主所寫的這種方式捕獲全局異常,只能捕獲到Controller裏拋出的異常,想要捕獲攔截器裏這個異常,需要在SpringMVC的配置文件中進行配置。
BUG修復
在SpringMVC配置文件中配置異常機制,如下:
<!-- 配置基於XML的異常機制 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" id="simpleMappingExceptionResolver">
<!-- 配置異常類型和具體視圖頁面的對應關係 -->
<property name="exceptionMappings">
<props>
<prop key="com.alageek.crowd.exception.AccessForbiddenException">admin-login</prop>
</props>
</property>
</bean>