• 中文
    • 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.1k
    • 请登录之后再进行评论

      登录

      赞助本站

      • 支付宝
      • 微信
      • QQ

      感谢一直支持本站的所有人!

      单栏布局 侧栏位置: