08.springMVC异常处理

142 阅读1分钟

回顾异常种类

异常通常分为受控异常和不受控异常。

  • 受控异常:通常直接继承自Exception的异常类。非运行时异常,即Exception中除了RuntimeException及其子类以外的。
  • 不受控异常:RuntimeException及其子类和Error及其子类

image-20230404133732698

SpringMVC中异常处理思路

1. 源码知识

DispatcherServlet是SpringMvc的入口,所有请求都经过DispatcherServlet,再进入我们定义的@Controller接口中,进行处理。接口发生异常时,也由DispatcherServlet的handlerExceptionResolvers属性所持有的HandlerExceptionResolver来处理。

image-20230404135149383

2. 统一异常处理

基于这个统一的异常处理类,我们系统中的dao、service、controller出现异常均可以向上层抛出,最后由DispatcherServlet的handlerExceptionResolvers统一处理。如下图:

image-20230404135658132

异常处理具体实现

实现的目标是统一在一个地方进行异常处理。

  • 如果是ArithmeticException的异常走error1.jsp
  • 如果是NullPointerException的异常走error2.jsp

1. 使用SimpleMappingExceptionResolver类

  • 采用配置文件方式

    修改 springmvc.xml文件如下:

    <!--自定义异常解析器-->
    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.ArithmeticException">redirect:/error1.jsp</prop>
                <prop key="java.lang.NullPointerException">redirect:/error2.jsp</prop>
            </props>
        </property>
    </bean>
    
  • 采用配置类方式

    @Configuration
    public class GlobalException1 {
        @Bean
        public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
            SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
            Properties prop = new Properties();
            prop.put("java.lang.NullPointerException","error1.jsp");
            prop.put("java.lang.ArithmeticException","error2.jsp");
            resolver.setExceptionMappings(prop);
            return resolver;
        }
    }
    

注意

上面两种方式采用其一便可。

2.使用HandlerExceptionResolver接口

@Component
public class GlobalException2 implements HandlerExceptionResolver {
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ModelAndView mv = new ModelAndView();
        if(ex instanceof ArithmeticException){
            mv.setViewName("error1.jsp");
        }
        if(ex instanceof NullPointerException){
            mv.setViewName("error2.jsp");
        }
        return mv;
    }
}

3.使用@ControllerAdvice+@ExceptionHandler注解

@ControllerAdvice
public class GlobalException3 {
    @ExceptionHandler(ArithmeticException.class)
    public ModelAndView handleArithmeticException() {
        ModelAndView mv =new ModelAndView();
        mv.setViewName("error1.jsp");
        return mv;
    }
​
    @ExceptionHandler(NullPointerException.class)
    public ModelAndView handleNullPointerException() {
        ModelAndView mv =new ModelAndView();
        mv.setViewName("error2.jsp");
        return mv;
    }
}

代码地址

gitee.com/mayuanfei/s…下的springmvc04

记忆印记

  • 受控异常Exception中除了RuntimeException及其子类以外的;不受控异常指RuntimeException+Error
  • 统一异常处理的核心思想是异常一直向上抛出,直到DispatcherServlet来统一处理
  • @ControllerAdvice+@ExceptionHandler是以后常用的。