Spring MVC之全局异常统一处理
一、SpringMVC异常处理
系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试等手段减少运行时异常的发生。
系统的Dao、Service、Controller出现都通过throws Exception向上抛出,最后由SpringMVC前端控制器交由异常处理器进行异常处理。
1.SpringMVC全局异常流程图
2.三种异常处理方式
① 使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver② 实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器③使用@ControllerAdvice和@ExceptionHandler注解实现异常拦截处理
1.SimpleMappingExceptionResolver
SpringMVC已经定义好了该类型转换器,在使用时可以根据项目情况进行相应异常与视图的映射配置
<!--配置简单映射异常处理器-->
<bean class=“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”>
<--默认错误视图-->
<property name=“defaultErrorView” value=“error”/>
<property name=“exceptionMappings”>
<map>
<--异常类型, 错误视图 -->
<entry key="cn.ybzy.common.exception.GlobalException " value="error"/>
<entry key="java.lang.ClassCastException" value="error"/>
</map>
</property>
</bean>
2. HandlerExceptionResolver
创建异常处理器类实现HandlerExceptionResolver接口即可。
public class GlobalException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
//处理异常的代码实现
//创建ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
return modelAndView;
}
}
3.使用@ControllerAdvice和@ExceptionHandler注解
自定义一个异常处理类,使用使用@ControllerAdvice和@ExceptionHandler注解,项目开发中常用此方式.
@ControllerAdvice
public class GlobalException {
@ExceptionHandler(Exception.class)
@ResponseBody
public HashMap<String, Object> error(Exception e) {
HashMap<String, Object> map = new HashMap<>();
map.put("status",0);
map.put("msg","系统异常!");
map.put("data",e.toString());
return map;
}
}
3.未捕获异常的处理
对于Unchecked Exception而言,由于代码不强制捕获,往往被忽略,如果运行期产生了Unchecked Exception,而代码中又没有进行相应的捕获和处理, 结果可想而知。
可以在web.xml中通过配置特定异常情况的显示页面,修改web.xml文件增加:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
二、全局异常统一处理
1、添加依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.2.8.RELEASE</spring.version>
</properties>
<!--spring-->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring集成web-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring mvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--Servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!--jsp-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
2、配置异常处理器
①使用注解方式,配置包扫描隔离
一般开发中,spring.xml与spring-mvc.xml是分开的,所以需要配置包扫描隔离。
- Spring配置文件
扫描所有注解 , 但排除扫描Controller注解
<context:component-scan base-package="cn.ybzy" annotation-config="true">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
2.Spring Mvc配置文件
use-default-filters=”false”关闭默认包扫描,只扫描Controller注解
<context:component-scan base-package="cn.ybzy" annotation-config="true" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
②使用xml方式
直接配置自定义异常类,交由spring创建该类实例。
<!-- 配置自定义异常处理器 -->
<bean id="handlerExceptionResolver" class="cn.ybzy.common.exception.GlobalException "/>
3、配置Spring Mvc以Json格式输出内容
方式一:引入jackson依赖,使用 <mvc:annotation-driven />注解驱动 默认底层就会集成jackson进行对象或集合的json格式字符串的转换
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
方式二,使用阿里的fastjson,在springmvc配置文件中进行如下配置:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value> text/html; charset=UTF-8</value>
<value> application/json; charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
4 、实现HandlerExceptionResolver接口的resolveException方法
@Component
public class GlobalException implements HandlerExceptionResolver {
private Logger logger = LoggerFactory.getLogger(GlobalException.class);
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
logger.error(httpServletRequest.getRequestURI() + " Exception:", e);
// MappingJackson2JsonView for jackson 2.x
// ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
ModelAndView modelAndView = new ModelAndView();
//1.使用jackson
MappingJacksonJsonView view = new MappingJacksonJsonView();
//2.使用fastjson
//FastJsonJsonView view = new FastJsonJsonView();
HashMap<String, Object> map = new HashMap<>();
if (e instanceof BusinessException){
map.put("status",0);
map.put("msg",e.getMessage());
map.put("data",e.toString());
view.setAttributesMap(map);
modelAndView.setView(view);
return modelAndView;
}else {
map.put("status",0);
map.put("msg","系统异常!");
map.put("data",e.toString());
view.setAttributesMap(map);
modelAndView.setView(view);
return modelAndView;
}
}
5、验证全局异常
@RequestMapping(value = "login",method = RequestMethod.GET)
@ResponseBody
public String login(){
int i=0;
int j=100/i;
return "Hello World!";
}
6、验证业务异常
@RequestMapping(value = "login",method = RequestMethod.GET)
@ResponseBody
public String login(){
int [] arr=new int[]{1,2,3};
if(arr.length<10){
throw new BusinessException("自定义业务异常!");
}
return "Hello World!";
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137151.html