• SpringMVC异常处理


    springMVC异常处理

    0x01_异常处理引入

    SpringMVC作为一个优秀的Web层开发框架,在框架中已经集成了异常处理机制,可以帮我们灵活地处理程序中发生的异常,提高了我们程序的稳定性,令我们对程序运行中发生的异常更加可以控制,这篇记录的就是SpringMVC框架中的对于异常的处理机制。
    本文中的所有程序都是基于SSM框架环境。对于搭建SSM环境有疑问的参考这篇文章:


    没有异常处理机制的时候吗,页面会出现类似这样的页面:

    image-20221112203501462

    对于用户来说,这样的提示并不友好。SpringMVC中对于这种情况的处理机制,就被称作是异常处理机制。该机制可以让用户访问程序的时候,如果发生程序异常,那么会选择一种友好的方式提醒用户。而且在正式开发中,完全可以由前端开发人员制作一个精美友好的错误页面,让用户可以获得良好的访问体验。

    系统中异常包括两类:预期异常(检查型异常)和运行时异常 RuntimeException,前者通过捕获异常从而获取异常信息, 后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

    系统的 dao、service、controller 出现都通过 throws Exception 向上抛出,最后由 springmvc 前端控制器交由异常处理器进行异常处理,如下图

    image-20221112203556726

    SpringMVC中对于异常的处理机制一共有三种,分别是:

    • SpringMVC内置异常处理机制SimpleMappingExceptionResolver
    • HandlerExceptionResolver自定义异常处理机制(实现自HandlerExceptionResolver)
    • @ExceptionHandler异常处理机制

    下面介绍了不止这些异常处理机制。

    0x02_@ExcepetionHandler局部异常处理器

    准备一个controller类:

    package com.bones.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    
    @Controller
    public class ExceptionTestController {
        @RequestMapping("demo1.do")
        public String testDemo1(){
            int i = 1/0;//模拟异常
            return "success.jsp";
        }
    
        @RequestMapping("demo2.do")
        public String testDemo2(){
            String s = null;
            System.out.println(s.length());
            return "success.jsp";
        }
    
        @ExceptionHandler(value = {ArithmeticException.class})
        public ModelAndView handleException(){
            ModelAndView mv = new ModelAndView();
            mv.setViewName("error1.jsp");
            return mv;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    其中访问demo1.do,因为有ArithmeticException所以会被捕获,执行handleException()方法,但是访问demo2.do,因为不是ArithmeticException所以页面还是报错:

    image-20221112210421124

    如果希望这个空指针异常也能被捕获的话,那么需要修改@ExceptionHandler注解的参数:

    @ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class})
    public ModelAndView handleException(){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("error1.jsp");
        return mv;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    简单看一下注解@ExceptionHandler的源码:

    image-20221112210621250

    value属性值需要传入一个Throwable类型的字节码。所以上面是这么写的:

    @ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class})
    
    • 1

    在Controller中写一个方法,并在该方法上使用@ExceptionHandler注解,当这个Controller中发生异常的时候,该注解的方法就会处理异常。

    value值不写的时候,默认就是不处理任何异常。

    这个注解的缺点就是:只能处理当前Controller中的异常。

    0x03_@ControllerAdvice+@ExceptionHandler全局异常处理器

    image-20221112211554385
    package com.bones.exceptionhandler;
    
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.servlet.ModelAndView;
    
    @ControllerAdvice
    public class GlobalExceptionHandler {
        @ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class})
        public ModelAndView handleException(){
            ModelAndView mv = new ModelAndView();
            mv.setViewName("error1.jsp");
            return mv;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注意要包扫描:applicationContext.xml

    <context:component-scan base-package="com.bones.service,com.bones.exceptionhandler"/>
    
    • 1

    注意:@ControllerAdvice+@ExceptionHandler定义的是全局异常处理器,但是如果controller内部还用@ExceptionHandler还定义异常处理,则controller中的异常处理优先于全局异常处理

    0x04_SimpleMappingExceptionResolver自定义全局异常解析器

    xml配置方式

    
    <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.ArithmeticException">redirect:/error1.jspprop>
                <prop key="java.lang.NullPointerException">redirect:/error2.jspprop>
            props>
        property>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    零XML方式配置

    image-20221112213419245

    GlobleExceptionHandler

    package com.bones.config;
    
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
    
    import java.util.Properties;
    
    @Configuration
    public class GlobleExceptionHandler {
        @Bean
        public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
            SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
            Properties properties = new Properties();
            properties.put("java.lang.ArithmeticException","error1.jsp");
            properties.put("java.lang.NullPointerException","error1.jsp");
            resolver.setExceptionMappings(properties);
            return resolver;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    注意还要加上包扫描:

    <context:component-scan base-package="com.bones.service,com.bones.config"/>
    
    • 1

    0x05_自定义一个HandlerExceptionResolver

    package com.bones.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.HandlerExceptionResolver;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @Configuration
    public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            ModelAndView mv = new ModelAndView();
            if (ex instanceof NullPointerException){
                mv.setViewName("error1.jsp");
            }
            if (ex instanceof ArithmeticException){
                mv.setViewName("error2.jsp");
            }
            mv.addObject("msg",ex);
            return mv;
    
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    以上4中SpringMVC的异常处理机制各有优劣,各位在使用SpringMVC的异常处理机制的时候,可以根据实际需求和自身喜好来进行配置开发。

  • 相关阅读:
    HTML网页设计制作——响应式网页影视动漫资讯bootstrap网页(9页)
    @ControllerAdvice + @ExceptionHandler 定义全局异常
    Dubbo快速入门
    (附源码)ssm失物招领系统 毕业设计 182317
    【opencv-c++】保存图片文件
    QT--day2
    软件系统运维方案
    云计算与大数据 第13章 云操作系统OpenStack习题带答案
    【c++20】‘std::allocator<char>::allocate‘: function does not take 2 arguments
    编译器工程师眼中的好代码:Loop Interchange
  • 原文地址:https://blog.csdn.net/qq_51550750/article/details/127858154