• 中文
    • English
  • 注册
  • 查看作者
  • SpringMVC:处理异常

    一.  使用try-catch处理Controller异常

    当单个Controller中的单个方法可能出现异常的时候,我们可以通过try-catch来跳转到自定义的异常页面。

    1. 首先新建spring-mvc.xml,并配置配置视图解析器、组件扫描器等

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/views/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    
        <context:component-scan base-package="io.zhangjia.springmvc"/>
    
        <mvc:default-servlet-handler/>
        <mvc:annotation-driven/>
    
    
    </beans>

    2.  配置web.xml

    采用和《SpringMVC:解决乱码和静态资源访问》一文中同样的配置

    3.  Controller

    package io.zhangjia.springmvc.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class Test {
    
        @RequestMapping("/testException")
        public String testException(Integer num, Model model) {
            try {
                int[] i = {1,2};
                model.addAttribute("index",i[num]);
                return "test";
            } catch (Exception e) {
                model.addAttribute("error",e);
                return "error/500";
            }
        }
    }

    上面的testException可能产生数组下表越界异常,如果发生异常,则转发到error文件夹下的500.jsp,如果没有发生异常,则转发到test页面

    4. views/ test.jsp

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
    <!DOCTYPE html>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>你好</h1>
    <h1>${requestScope.index}</h1>
    </body>
    </html>

    5.  error/500.jsp

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
    <!DOCTYPE html>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>500页面</h1>
    <h1>${requestScope.error}</h1>
    </body>
    </html>

    二.  使用SpringMVC处理单个Controller中的异常

    上面的例子中,一个Controller只有一个方法可能产生异常,但是如果一个Controller中有多个方法,每个方法都有可能产生异常,那么采用try-catch的方法就显的十分繁琐。

    我们可以使用SpringMVC来统一处理单个Controller中的所有方法可能产生的异常

    package io.zhangjia.springmvc.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller
    public class Test {
    
        @RequestMapping("/test1")
        public String testException1(Integer num, Model model) {
            int[] i = {1, 2};
            model.addAttribute("index", i[num]);
            return "test";
        }
    
    
        @RequestMapping("/test2")
        public String testException2(Integer num, Model model) {
            model.addAttribute("result", 10 / num);
            return "test";
        }
    
    
        @ExceptionHandler
        public ModelAndView exception1(Exception e) {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("error/500");
            modelAndView.addObject("error",e);
            return modelAndView;
        }
    }

    上面的exception1可以处理该Controller中所有可能产生的异常,我们也可以在@ExceptionHandler注解中通过({,…,…})的方法针对某种异常单独处理。

    package io.zhangjia.springmvc.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller
    public class Test {
    
        @RequestMapping("/test1")
        public String testException1(Integer num, Model model) {
            int[] i = {1, 2};
            model.addAttribute("index", i[num]);
            return "test";
        }
    
    
        @RequestMapping("/test2")
        public String testException2(Integer num, Model model) {
            model.addAttribute("result", 10 / num);
            return "test";
        }
    
        @ExceptionHandler({ArithmeticException.class,ArrayIndexOutOfBoundsException.class})
        public ModelAndView exception1(Exception e) {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("error/500");
            modelAndView.addObject("error",e);
            return modelAndView;
        }
    }

    我们还可以将每个可能产生的异常分开处理,并且有两种处理方法,方法一:

    @ExceptionHandler({ArithmeticException.class})
    public ModelAndView exception1(Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("error/500");
        modelAndView.addObject("error",e);
        return modelAndView;
    }
    
    @ExceptionHandler({ArrayIndexOutOfBoundsException.class})
    public ModelAndView exception2(Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("error/500");
        modelAndView.addObject("error",e);
        return modelAndView;
    }

    方法二:

    @ExceptionHandler
    public ModelAndView exception1(ArithmeticException e) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("error/500");
        modelAndView.addObject("error",e);
        return modelAndView;
    }
    
    @ExceptionHandler
    public ModelAndView exception2(ArrayIndexOutOfBoundsException e) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("error/500");
        modelAndView.addObject("error",e);
        return modelAndView;
    }

    三.  使用SpringMVC处理所有的Controller中的异常

    在第二节中,我们处理的异常都是针对单个Controller进行的,但是如果一个项目中有成百上千个Controller,那么上面的方法也显得太过繁琐,针对所有的Controller中的所有异常,我们可以新建一个专门用于异常处理的Controller,然后为其添加@ControllerAdvice注解。首先模拟两个可能产生异常的Controller:添加Test1:

    @Controller
    public class Test {
    
        @RequestMapping("/test1")
        public String testException1(Integer num, Model model) {
            int[] i = {1, 2};
            model.addAttribute("index", i[num]);
            return "test";
        }
    }

    添加Test2:

    @Controller
    public class Test2 {
    
        @RequestMapping("/test2")
        public String testException2(Integer num, Model model) {
            model.addAttribute("result", 10 / num);
            return "test";
        }
    
    
    }

    接下来添加处理所有异常的Controller:

    package io.zhangjia.springmvc.controller;
    
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.servlet.ModelAndView;
    
    @ControllerAdvice
    public class ExceptionController {
        @ExceptionHandler
        public ModelAndView exception(Exception e) {
            System.out.println("e = " + e);
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("error/500");
            modelAndView.addObject("error",e);
            return modelAndView;
        }
    }

    现在项目中的所有Controller中的所有异常,都会被统一处理。

    四.  总结

    1.  如果要处理单个Controller中的某一个方法的异常:

    • 方法一:可以使用try-catch的方法,try中return正确的路径,catch中return错误页面的路径。

    • 方法二:在Controller中专门添加一个用于处理异常的方法,并添加@ExceptionHandler注解中,然后为注解添加参数,参数即为XXXException.class

    • 方法三:给Controller中用于处理异常的方法的形参设置为需要处理的异常类型。

    2.  如果要处理单个Controller中的所有方法中可能产生的异常,可以在该Controller专门添加一个处理异常的方法,并为其添加 @ExceptionHandler 注解

    3.  如果要处理所有的Controller中的所有方法中可能产生的异常,则需要创建一个专门用于处理异常的Controller,为该类添加@ControllerAdvice注解,并在该类中添加用于处理异常的方法

  • 0
  • 0
  • 0
  • 1.4k
  • 请登录之后再进行评论

    登录
    单栏布局 侧栏位置: