Spring MVC之全局异常统一处理

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 Spring MVC之全局异常统一处理,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、SpringMVC异常处理

系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试等手段减少运行时异常的发生。

系统的Dao、Service、Controller出现都通过throws Exception向上抛出,最后由SpringMVC前端控制器交由异常处理器进行异常处理。

1.SpringMVC全局异常流程图

1.请求

1

1

1

2.异常

2.异常

2.异常

2.异常

3.包装异常

4.包装异常

客户端

DispatcherServlet

Controller

Service

Dao

HandlerExceptionResolver

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是分开的,所以需要配置包扫描隔离。
  1. 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

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!