一. 使用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注解,并在该类中添加用于处理异常的方法
请登录之后再进行评论