SpringMVC 异常处理
本文内容纲要:
-UsingHTTPStatusCodes
-ControllerBasedExceptionHandling
-GlobalExceptionHandling
-GoingDeeper
UsingHTTPStatusCodes
在我们自定义的异常上使用ResponseStatus注解。当我们的Controller抛出异常,并且没有被处理的时候,他将返回HTTPSTATUS为指定值的HTTPRESPONSE,比如:
@ResponseStatus(value=HttpStatus.NOT_FOUND,reason="NosuchOrder")//404
publicclassOrderNotFoundExceptionextendsRuntimeException{
//...
}
我们的Controller为:
@RequestMapping(value="/orders/{id}",method=GET)
publicStringshowOrder(@PathVariable("id")longid,Modelmodel){
Orderorder=orderRepository.findOrderById(id);
if(order==null)thrownewOrderNotFoundException(id);
model.addAttribute(order);
return"orderDetail";
}
这时候会返回404,转到404页面而不是错误页面
ControllerBasedExceptionHandling
在一个Controller中,通过增加使用注解@ExceptionHandler的方法来处理@RequestMapping方法抛出的异常,注意这种只在单个Controller中有效。这么做可以:
- 发生异常后,改变Responsestatus,一般而言,发生异常返回HTTPSTATUS500.我们可以变为其他。
- 发生错误后转到错误页面
- 可以为不同异常定义不同处理(如不同的错误页面,不同的Responsestatus)
举例说明
@Controller
publicclassExceptionHandlingController{
//我们标注了@RequestMapping的方法
...
//处理异常的方法。
//把我们定义的异常转换为特定的Httpstatuscode
@ResponseStatus(value=HttpStatus.CONFLICT,reason="Dataintegrityviolation")//409
@ExceptionHandler(DataIntegrityViolationException.class)
publicvoidconflict(){
//Nothingtodo
}
//捕获到SQLException,DataAccessException异常之后,转到特定的页面。
@ExceptionHandler({SQLException.class,DataAccessException.class})
publicStringdatabaseError(){
//仅仅转到错误页面,我们在页面上得不到这个Exception的值,要得到值,我们可以通过下面的方法得到
return"databaseError";
}
//通过ModelAndView返回页面,以及往页面传相应的值
@ExceptionHandler(Exception.class)
publicModelAndViewhandleError(HttpServletRequestreq,Exceptionexception){
logger.error("Request:"+req.getRequestURL()+"raised"+exception);
ModelAndViewmav=newModelAndView();
mav.addObject("exception",exception);
mav.addObject("url",req.getRequestURL());
mav.setViewName("error");
returnmav;
}
}
GlobalExceptionHandling
在类上使用@ControllerAdvice注解,可以使得我们处理整个程序中抛出的异常。然后在类中的方法上使用@ExceptionHandler来定义处理不同的异常。
举例:
classGlobalControllerExceptionHandler{
@ResponseStatus(HttpStatus.CONFLICT)//409
@ExceptionHandler(DataIntegrityViolationException.class)
publicvoidhandleConflict(){
//Nothingtodo
}
//转到特定页面。。。。。
}
如果我们要处理程序中所有的异常可以这么做:
@ControllerAdvice
classGlobalDefaultExceptionHandler{
publicstaticfinalStringDEFAULT_ERROR_VIEW="error";
@ExceptionHandler(value=Exception.class)
publicModelAndViewdefaultErrorHandler(HttpServletRequestreq,Exceptione)throwsException{
//Iftheexceptionisannotatedwith@ResponseStatusrethrowitandlet
//theframeworkhandleit-liketheOrderNotFoundExceptionexample
//atthestartofthispost.
//AnnotationUtilsisaSpringFrameworkutilityclass.
if(AnnotationUtils.findAnnotation(e.getClass(),ResponseStatus.class)!=null){
throwe;
}
//Otherwisesetupandsendtheusertoadefaulterror-view.
ModelAndViewmav=newModelAndView();
mav.addObject("exception",e);
mav.addObject("url",req.getRequestURL());
mav.setViewName(DEFAULT_ERROR_VIEW);
returnmav;
}
}
GoingDeeper
实现HandlerExceptionResolver接口,SpringMvc可以使用他来处理Controller中抛出的异常
publicinterfaceHandlerExceptionResolver{
ModelAndViewresolveException(HttpServletRequestrequest,
HttpServletResponseresponse,Objecthandler,Exceptionex);
}
SpringMvc使用三种默认的HandlerExceptionResolver来处理我们的异常
- ExceptionHandlerExceptionResolver:处理匹配@ExceptionHandler定义的异常。
- ResponseStatusExceptionResolver:处理添加@ResponseStatus注解的异常
- DefaultHandlerExceptionResolver:把Spring定义的一些标准异常,转换为HTTPSTATUSCODE.
Spring内置的SimpleMappingExceptionResolver实现了HandlerExceptionResolver接口,也是我们经常使用的,XML配置如下:
<beanid="simpleMappingExceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<propertyname="exceptionMappings">
<map>
<!--key为异常类型,value为要转到的页面-->
<entrykey="DatabaseException"value="databaseError"/>
<entrykey="InvalidCreditCardException"value="creditCardError"/>
</map>
</property>
<!--默认的异常页面-->
<propertyname="defaultErrorView"value="error"/>
<!--在页面我们可以通过ex拿到异常信息-->
<propertyname="exceptionAttribute"value="ex"/>
<!--Nameofloggertousetologexceptions.Unsetbydefault,sologgingdisabled-->
<!--log异常信息,默认不设置-不记录异常信息-->
<propertyname="warnLogCategory"value="example.MvcLogger"/>
</bean>
本文内容总结:UsingHTTPStatusCodes,ControllerBasedExceptionHandling,GlobalExceptionHandling,GoingDeeper,
原文链接:https://www.cnblogs.com/hupengcool/p/4586910.html