index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>首页</title>
</head>
<body>
<a href="./userinfo/toView.do?i=0">链接</a>
</html>
这里返回i=0的值
UserInfoController.java
package com.jd.userinfo;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
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;
import com.jd.vo.UserInfo;
@Controller
public class UserInfoController {
@ExceptionHandler({ArithmeticException.class})
public ModelAndView exception(Exception e) {//出現java.lang.ArithmeticException异常时交由该方法处理
System.out.println(e.getMessage());
ModelAndView modelAndView = new ModelAndView("/userinfo/error");
modelAndView.addObject("exception", e);
return modelAndView;
}
@RequestMapping("/userinfo/toView.do")
public String toView(int i) {
System.out.println(1/i);
return "to";
}
}
Spring MVC 通过HandlerExceptionResolver接口处理程序的异常,包括Handler 映射、数据绑定以及目标方法执行时发生的异常;ExceptionHandlerExceptionResolver、DefaultHandlerExceptionResolver、ResponseStatusExceptionResolver和SimpleMappingExceptionResolver为HandlerExceptionResolver接口常用实现类,如果使用<mvc:annotation-driven></mvc:annotation-driven>,则SpringMVC自动注册ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver;
该视图解析器用于处理 Handler 中用 @ExceptionHandler 注解所修饰的方法
@ExceptionHandler注解所修饰方法的参数列表可以加入Exception类型的参数,该参数的值即为对应发生的异常对象;但不能是Map类型,可以使用 ModelAndView作为该方法返回值,进而将异常信息传到页面上,页面通过${exception.message }即可显示错误信息
这里也可以改为:
@ExceptionHandler({ArithmeticException.class})
public String exception(Exception e) {//出現java.lang.ArithmeticException异常时交由该方法处理
System.out.println(e.getMessage());
return "error";
}
application.xml中添加:
<mvc:annotation-driven></mvc:annotation-driven>
<?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:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 自动扫描com.jd包及其子包,并实例化被@Component、@Service、@Repository或@Controller等注解所修饰的类 -->
<context:component-scan base-package="com.jd"></context:component-scan>
<!-- 视图解释器用于将逻辑视图转换为物理视图:将handler方法(如UserInfoController中的get方法)返回值解析为实际的物理视图,
InternalResourceViewResolver视图解析器将handler方法返回值解析为"prefix+返回值+suffix"(如/WEB-INF/views/result.jsp)物理视图,
并做请求转发操作 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/view/" p:suffix=".jsp">
</bean>
<!-- 配置BeanName视图解析器:使用视图名字解析视图 -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<!-- order属性用于设定视图解析器的优先级,order值越小优先级越高,InternalResourceViewResolver优先级为Integer所能表示的最大值 -->
<property name="order" value="0"></property>
</bean>
<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
下面讨论异常的优先级:
一个Controller类有多个@ExceptionHandler 注解修饰的方法则使用当前异常继承最近的@ExceptionHandler注解修饰方法处理异常。
UserInfoController.java修改为:
package com.jd.userinfo;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
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;
import com.jd.vo.UserInfo;
@Controller
public class UserInfoController {
@ExceptionHandler({Exception.class})
public ModelAndView exception(Exception e) {
System.out.println("exception方法:"+e.getMessage());
ModelAndView modelAndView = new ModelAndView("/userinfo/error");
modelAndView.addObject("exception", e);
return modelAndView;
}
@ExceptionHandler({RuntimeException.class})
public ModelAndView runtimeException(Exception e) {
System.out.println("runtimeException方法:"+e.getMessage());
ModelAndView modelAndView = new ModelAndView("/userinfo/error");
modelAndView.addObject("exception", e);
return modelAndView;
}
@RequestMapping("/userinfo/toView.do")
public String toView(int i) {
System.out.println(1/i);
return "to";
}
}
这里有两个异常处理方法:
因为客户端发送http://localhost:8080/moon/userinfo/toView.do?i=0请求,服务器端发生ArithmeticException异常,由于该异常直接继承RuntimeException,所以使用runtimeException(Exception e)方法处理异常。
这里添加:
ArithmeticExceptionHandler.java类:
package com.jd.userinfo;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice//该注解需要配置<mvc:annotation-driven></mvc:annotation-driven>
public class ArithmeticExceptionHandler {
@ExceptionHandler({ArithmeticException.class})
public ModelAndView exception(Exception e) {
System.out.println(e.getMessage());
ModelAndView modelAndView = new ModelAndView("/userinfo/error");
modelAndView.addObject("exception", e);
return modelAndView;
}
}
这里是@ControllerAdvice注解:
1、该注解仅修饰类;
2、如果当前Controller中没有找到@ExceptionHandler注解所修饰的方法来处理当前异常,则去@ControllerAdvice标记的类中查找@ExceptionHandler标记的方法。
流程:
1、客户端发起http://localhost:8080/moon/userinfo/toView.do?i=0请求;
2、服务器端发生ArithmeticException异常;
3、UserInfoController类中没有找到处理此异常的@ExceptionHandler注解修饰的方法;
4、去@ControllerAdvice标记所修饰的HandleException类中查找@ExceptionHandler标记的方法,找到并执行exception(Exception e)方法;