異常,異常
我們一定要捕獲一切該死的異常,寧可錯殺一千也不能放過一個!
產品上線后的異常更要命,一定要屏蔽錯誤內容,以免暴露敏感信息!
在用Spring MVC開發WEB應用時捕獲全局異常的方法基本有兩種,
-
WEB.XML,就是指定error-code和page到指定地址,這也是最傳統和常見的做法
-
用Spring的全局異常捕獲功能,這種相對可操作性更強一些,可根據自己的需要做一后善后處理,比如日志記錄等。
SO,本文列出Spring-MVC做WEB開發時常用全局異常捕獲的幾種解決方案拋磚引玉
互相沒有依賴,每個都可單獨使用!
定義服務器錯誤WEB.XML整合Spring MVC
web.xml
<error-page>
<error-code>404</error-code>
<location>/404</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500</location>
</error-page>
<!-- 未捕獲的錯誤,同樣可指定其它異常類,或自定義異常類 -->
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/uncaughtException</location>
</error-page>
applicationContext.xml
<!-- 錯誤路徑和錯誤頁面,注意指定viewResolver -->
<mvc:view-controller path="/404" view-name="404"/>
<mvc:view-controller path="/500" view-name="500"/>
<mvc:view-controller path="/uncaughtException" view-name="uncaughtException"/>
Spring全局異常,代碼入侵方式
異常拋出
@Controller
public class MainController {
@ResponseBody
@RequestMapping("/")
public String main(){
throw new NullPointerException("NullPointerException Test!");
}
}
異常捕獲
//注意使用注解@ControllerAdvice作用域是全局Controller范圍
//可應用到所有@RequestMapping類或方法上的@ExceptionHandler、@InitBinder、@ModelAttribute,在這里是@ExceptionHandler
@ControllerAdvice
public class AControllerAdvice {
@ExceptionHandler(NullPointerException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public String handleIOException(NullPointerException ex) {
return ClassUtils.getShortName(ex.getClass()) + ex.getMessage();
}
}
Spirng全局異常,配置方式
異常拋出,同上!
異常捕獲
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 默認錯誤頁面,就是不在exceptionMappings指定范圍內 -->
<property name="defaultErrorView" value="uncaughtException" />
<property name="exceptionMappings">
<props>
<!-- 異常類名,可以是全路徑,錯誤頁面或Controller路徑! -->
<prop key=".NullPointerException">NullPointerException</prop>
<prop key="java.io.IOException">IOException</prop>
</props>
</property>
</bean>
Sping全局異常,自定義異常類和異常解析
自定義異常類:
public class CustomException extends RuntimeException {
public CustomException(){
super();
}
public CustomException(String msg, Throwable cause){
super(msg, cause);
//Do something...
}
}
拋出異常
@ResponseBody
@RequestMapping("/ce")
public String ce(CustomException e){
throw new CustomException("msg",e);
}
實現異常捕獲接口HandlerExceptionResolver
public class CustomHandlerExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("e", e);
//這里可根據不同異常引起類做不同處理方式,本例做不同返回頁面。
String viewName = ClassUtils.getShortName(e.getClass());
return new ModelAndView(viewName, model);
}
}
配置Spring支持異常捕獲
<bean class="cn.bg.controller.CustomHandlerExceptionResolver"/>
完!