Spring MVC的三种异常处理方式实例详解

 更新时间:2024年01月03日 09:06:10   作者:残城碎梦  
在SpringMVC 中,不管是编译异常还是运行时异常,都可以最终由 SpringMVC提供的异常处理器进行统一处理,这样就避免了随时随地捕获处理的繁琐性,这篇文章主要介绍了Spring MVC的三种异常处理方式 ,需要的朋友可以参考下

Spring MVC异常的处理流程

异常分为编译时异常和运行时异常,编译时异常我们 try-catch进行捕获,捕获后自行处理,而运行时异常是不 可预期的,就需要规范编码来避免,在SpringMVC 中,不管是编译异常还是运行时异常,都可以最终由 SpringMVC提供的异常处理器进行统一处理,这样就避免了随时随地捕获处理的繁琐性。

 SpringMVC 处理异常的思路是,一路向上抛,都抛给前端控制器 DispatcherServlet ,DispatcherServlet 在调用异常处理器ExceptionResolver进行处理,如下图:

Spring MVC异常的处理方式

SpringMVC 提供了以下三种处理异常的方式:

  • 简单异常处理器:使用SpringMVC 内置的异常处理器处理SimpleMappingExceptionResolver;
  • 自定义异常处理器:实现HandlerExceptionResolver接口,自定义异常进行处理;
  • 注解方式:使用@ControllerAdvice + @ExceptionHandler 来处理

简单异常处理器SimpleMappingExceptionResolver

配置开启SimpleMappingExceptionResolver, 并指定异常捕获后的处理动作,当发生了异常后,会被 SimpleMappingExceptionResolver 处理,跳转到我们 配置的错误页面error.html给用户进行友好展示 。

<!--配置简单异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <!-- 异常捕获后动作:展示视图 -->
    <property name="defaultErrorView" value="/error.html"/>
</bean

可以在配置SimpleMappingExceptionResolver时,指定一些参数,例如:异常的类型

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="defaultErrorView" value="/error.html"/>
    <property name="exceptionMappings">
        <props>
            <!-- 配置异常类型对应的展示视图 -->
            <prop key="java.lang.RuntimeException">/error.html</prop>
            <prop key="java.io.FileNotFoundException">/io.html</prop>
        </props>
    </property>
</bean> 

注解方式配置简单映射异常处理器 

@Bean
public SimpleMappingExceptionResolver simpleMappingExceptionResolver(){
    //创建SimpleMappingExceptionResolver
    SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
    //设置默认错误展示视图
    resolver.setDefaultErrorView("/error.html");
    //定义Properties设置特殊异常对应的映射视图
    Properties properties = new Properties();
    properties.setProperty("java.lang.RuntimeException","/error.html");
    properties.setProperty("java.io.FileNotFoundException","/io.html");
    resolver.setExceptionMappings(properties);
    return resolver;
}

自定义异常处理器

实现HandlerExceptionResolver接口自定义异常处理器,可以完成异常逻辑的处理。

public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
    @Override
    //参数Object是当前目标方法处理器对象HandlerMethod
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, 
                                         HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("/error.html");
        return modelAndView;
    }
}

交给Spring管理异常处理器:

<bean class="com.fly.exception.MyHandlerExceptionResolver"></bean>

自定义异常处理器,返回Json格式字符串信息

@Component
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, 
                                         HttpServletResponse httpServletResponse, Object o, Exception e) {
        //编写要返回的json格式的字符串
        String jsonStr = "{\"code\":0,\"message\":\"error\",\"data\":\"\"}";
        try {
            httpServletResponse.getWriter().write(jsonStr);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        return null;
    }
}

@ControllerAdvice + @ExceptionHandler 配置异常

@ControllerAdvice 注解本质是一个 @Component,也会被扫描到,与此同时,具备AOP功能,默认情况下对所有的Controller都进行拦截操作, 拦截后干什么呢?就需要再结合@ExceptionHandler、@InitBinder、@ModelAttribute 注解一起使用了,此 处我们讲解的是异常,所以是@ControllerAdvice + @ExceptionHandler的组合形式编写全局异常处理器类,使用@ControllerAdvice标注,且@ExceptionHandler指定异常类型。

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(RuntimeException.class)
    public ModelAndView runtimeHandleException(RuntimeException e){
        System.out.println("全局异常处理器执行...."+e);
        ModelAndView modelAndView = new ModelAndView("/error.html");
        return modelAndView;
    }
    @ExceptionHandler(IOException.class)
    @ResponseBody
    public ResultInfo ioHandleException(IOException e){
        //模拟一个ResultInfo
        ResultInfo resultInfo = new ResultInfo(0,"IOException",null);
        return resultInfo;
    }
}

如果全局异常处理器响应的数据都是Json格式的字符串的话,可以使用@RestControllerAdvice替代 @ControllerAdvice 和 @ResponseBody

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(RuntimeException.class)
    public ResultInfo runtimeHandleException(RuntimeException e){
        //模拟一个ResultInfo
        ResultInfo resultInfo = new ResultInfo(0,"RuntimeException",null);
        return resultInfo;
    }
    @ExceptionHandler(IOException.class)
    public ResultInfo ioHandleException(IOException e){
        //模拟一个ResultInfo
        ResultInfo resultInfo = new ResultInfo(0,"IOException",null);
        return resultInfo;
    }
}

到此这篇关于Spring MVC的三种异常处理方式的文章就介绍到这了,更多相关Spring MVC异常处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Springboot如何去掉URL后面的jsessionid

    Springboot如何去掉URL后面的jsessionid

    这篇文章主要介绍了Springboot如何去掉URL后面的jsessionid,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java线程实现时间动态显示

    Java线程实现时间动态显示

    这篇文章主要为大家详细介绍了Java线程实现时间动态显示,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04
  • spring启动后保证创建的对象不被垃圾回收器回收

    spring启动后保证创建的对象不被垃圾回收器回收

    最近看到一个问题是,spring在启动后如何保证创建的对象不被垃圾回收器回收?。所以本文结合jvm的垃圾回收机制和spring中的源代码做出自己的一点猜测。有需要的朋友们可以参考借鉴。
    2016-09-09
  • Spring Security获取用户认证信息的实现流程

    Spring Security获取用户认证信息的实现流程

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI和AOP功能,为应用系统提供声明式的安全访问控制功能
    2022-12-12
  • Spring Boot FeignClient 如何捕获业务异常信息

    Spring Boot FeignClient 如何捕获业务异常信息

    这篇文章主要介绍了Spring Boot FeignClient 如何捕获业务异常信息的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • SpringBoot自动配置与启动流程详细分析

    SpringBoot自动配置与启动流程详细分析

    这篇文章主要介绍了SpringBoot自动配置原理分析,SpringBoot是我们经常使用的框架,那么你能不能针对SpringBoot实现自动配置做一个详细的介绍。如果可以的话,能不能画一下实现自动配置的流程图。牵扯到哪些关键类,以及哪些关键点
    2022-11-11
  • 使用Zxing实现二维码生成器内嵌图片

    使用Zxing实现二维码生成器内嵌图片

    二维码在现实中的应用已经很广泛了,本文介绍了使用Zxing实现二维码生成器内嵌图片,有需要的可以了解一下。
    2016-10-10
  • IDEA如何实现批量修改变量名

    IDEA如何实现批量修改变量名

    这篇文章主要介绍了IDEA如何实现批量修改变量名问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • 分析并发编程之LongAdder原理

    分析并发编程之LongAdder原理

    LongAdder类是JDK1.8新增的一个原子性操作类。AtomicLong通过CAS算法提供了非阻塞的原子性操作,相比受用阻塞算法的同步器来说性能已经很好了,但是JDK开发组并不满足于此,因为非常搞并发的请求下AtomicLong的性能是不能让人接受的
    2021-06-06
  • Java编程子类能否重写父类的静态方法探索

    Java编程子类能否重写父类的静态方法探索

    关于子类能否重写父类的静态方法,对像我这种初级的编程爱好者来说仍是值得讨论的一件事,下面我们通过具体实例,对此问题进行简单的探索。
    2017-10-10

最新评论