美文网首页个人学习
Spring MVC异常处理

Spring MVC异常处理

作者: BlueSkyBlue | 来源:发表于2020-02-14 18:21 被阅读0次

Spring MVC通过HandlerExceptionResolver处理程序的异常,包括Handler映射、数据绑定以及目标方法执行时发生的异常。

Spring MVC提供HandlerExceptionResolver的实现类。

DispatcherServlet默认装配HandlerExceptionResolver。没有使用<mvc:annotation-driven/>配置:

  • AnnotationMethodHandlerExceptionResolver
  • ResponseStatusExceptionResolver
  • DefaultHandlerExceptionResolver

使用了<mvc:annotation-driven/>配置

  • ExceptionHandlerExceptionResolver
  • ResponseStatusExceptionResolver
  • DefaultHandlerExceptionResolver

ExceptionHandlerExceptionResolver

主要处理Handler中用@ExceptionHandler注解定义的方法。@ExceptionHandler方法的入参中可以加入Exception类型的参数,该参数即对应发生的异常对象。

示例

  1. 首先我们要先写页面
<a href="testExceptionHandlerExceptionResolver?i=0">
  Test ExceptionHandlerExceptionResolver
</a>
  1. 之后是Java代码
@RequestMapping("testExceptionHandlerExceptionResolver")
public String testExceptionHandlerExceptionResolver(@RequestParam("i")
                                                       int i){
    System.out.println("Number " + (10/i));
    return "success";
}
  1. 我们知道0是不能作为除数的,因此该程序必然抛出异常。之后我们就要捕获这个异常就需要用到ExceptionHandler。
@ExceptionHandler({ArithmeticException.class})
public String handleArithmeticException(Exception ex){
    System.out.println("Exception: " + ex);
    return "error";
}
  1. 此时又有一个问题,我们如何将该异常显示在页面上。@ExceptionHandler方法的入参中不能传入Map,若希望将异常信息传导到页面上,需要使用ModelAndView作为返回值。
@ExceptionHandler({ArithmeticException.class})
public ModelAndView handleArithmeticException(Exception ex){
    ModelAndView mv = new ModelAndView("error");
    mv.addObject("exception", ex);
    return mv;
}
  1. 之后是修改异常页面
<body>
   <h4>Error Page</h4>
   <br><br>
   ${exception }
</body>

@ExceptionHandler标记的方法有优先级的问题。假设@ExceptionHandler中定义了两个异常。程序一旦发现异常,则程序会寻找最为接近的异常并将其抛出。

@ControllerAdvice:如果在当前Handler中找不到@ExceptionHandler方法来处理当前方法出现的异常,则将去@ControllerAdvice的类中查找@ExceptionHandler标记的方法来处理异常。例如:

@ControllerAdvice
public class HandleException {
    
    @ExceptionHandler({ArithmeticException.class})
    public ModelAndView handleArithmeticException(Exception ex){
        ModelAndView mv = new ModelAndView("error");
        mv.addObject("exception", ex);
        return mv;
    }
}

ResponseStatusExceptionResolver

  1. 首先我们先自定义一个异常类:
@ResponseStatus(value=HttpStatus.FORBIDDEN, reason="Username does not match password.")
public class UsernameMatchPasswordException extends RuntimeException{
    private static final long serialVersionUID = 1L;
}

注意:这里我们使用了@ResponseStatus注解,其中有两个参数。value代表Http返回码,reason注明请求失败的原因。

  1. 之后我们编写测试代码:
@RequestMapping("testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
    if(i == 13){
        throw new UsernameMatchPasswordException();
    }
    System.out.println("testResponseStatusExceptionResolver...");
    return "success";
}

在i等于13的时候抛出我们刚刚定义的异常。并返回请求失败的页面。

  1. 我们也可以在测试方法上定义@ResponseStatus注解。这样不论i等于多少最后都会返回注解指定的状态。
@ResponseStatus(reason="Testing...", value=HttpStatus.NOT_FOUND)
@RequestMapping("testResponseStatusExceptionResolver")
public String testResponseStatusExceptionResolver(@RequestParam("i") int i){
    if(i == 13){
        throw new UsernameMatchPasswordException();
    }
    System.out.println("testResponseStatusExceptionResolver...");
    return "success";
}

DefaultHandlerExceptionResolver

对一些特殊的异常进行处理,比如NoSuchRequestHandlingMethodException, HttpRequestMethodNotSupportedException, HttpMediaTypeNotSupportedException, HttpMediaTypeNotAcceptableException等。

SimpleMappingExceptionResolver

如果希望对所有的异常进行统一处理,可以使用SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常。

我们现在要创建一个异常的请求,如下代码所示:

@RequestMapping("testSimpleMappingExceptionResolver")
public String testSimpleMappingExceptionResolver(@RequestParam("i") int i){
    String [] vals = new String[10];
    System.out.println(vals[i]);
    return "success";
}

我们发出如下的请求

<a href="testSimpleMappingExceptionResolver?i=10">Test SimpleMappingExceptionResolver</a>

由于数组的上限是9,,10肯定是越界的了。此时后台必然发出java.lang.ArrayIndexOutOfBoundsException异常。

此时我们需要在配置文件中进行配置,跳转到我们希望显示的错误界面中。

<bean
        class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  <property name="exceptionMappings">
   <props>
     <prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
   </props>
  </property>
 </bean>

此时异常会抛出到error界面。

相关文章

网友评论

    本文标题:Spring MVC异常处理

    本文链接:https://www.haomeiwen.com/subject/iyudfhtx.html