当前位置: 首页 > 编程笔记 >

Spring MVC中异常处理的三种方式

微生宝
2023-03-14
本文向大家介绍Spring MVC中异常处理的三种方式,包括了Spring MVC中异常处理的三种方式的使用技巧和注意事项,需要的朋友参考一下

前言

在 SpringMVC, SpringBoot 处理 web 请求时, 若遇到错误或者异常,返回给用户一个良好的错误信息比 Whitelabel Error Page 好的多。 SpringMVC 提供了三种异常处理方式, 良好的运用它们可以给用户提供可读的错误信息。

1. 实现 HandlerExceptionResolver

public class AppHandlerExceptionResolver implements HandlerExceptionResolver {
 @Override
 public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
  ModelAndView mav = new ModelAndView();
  mav.addObject("message", ex.getMessage());
  // 可以设置视图名导向错误页面
  mav.setViewName("/error");
  // 直接返回视图
  // 如果返回 null,则会调用下一个 HandlerExceptionResolver
  return mav;
 }
}

然后配置一个 HandlerExceptionResolver

@Bean
public AppHandlerExceptionResolver appHandlerExceptionResolver() {
 return new AppHandlerExceptionResolver();
}

HandlerExceptionResolver 的实现类会 catch 到 @Controller 方法执行时发生的异常,处理后返回 ModelAndView 作为结果视图,因此可以通过它来定制异常视图。

HandlerExceptionResolver 只能捕获 @Controller 层发生的异常(包括 @Controller 调用 @Service 发生的异常),其他地方的异常,比如访问了一个不存在的路径,不会被 HandlerExceptionResolver 捕获,此时会跳到 ErrorController 处理, 下面会说到。

2. 通过 @ControllerAdvice 和 @ExceptionHandler 注解

// 可以配置拦截指定的类或者包等
// @RestControllerAdvice 使 @ExceptionHandler 注解的方法默认具有 @ResponseBody 注解
@RestControllerAdvice(basePackageClasses = HelloWorldController.class)
public class AppExceptionHandlerAdvice {

 // 配置拦截的错误类型
 // 这里也可以返回 ModelAndView 导向错误视图
 @ExceptionHandler(Exception.class)
 public ResponseEntity<Object> responseEntity(Exception e) {
  HttpHeaders headers = new HttpHeaders();
  headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
  Map<String, Object> map = new HashMap<>();
  map.put("status", 400);
  map.put("message", e.getMessage());
  // 直接返回结果
  return new ResponseEntity<>(map, headers, HttpStatus.BAD_REQUEST);

 }
}

这种方式配置的异常处理由 HandlerExceptionResolver 的默认实现类 HandlerExceptionResolverComposite 处理,因此也只能捕获 @Controller 层的异常。

@ExceptionHandler 可以返回 ModelAndView 定制异常视图。

@ControllerAdvice 可以拦截特定的类,@ExceptionHandler 可以拦截特定的异常,因此可以更精确的配置异常处理逻辑。

@ExceptionHandler 可以在 @Controller 类中声明,此时只能处理同一个类的异常

3. 自定义 ErrorController bean

@RestController
@RequestMapping("/error")
public class AppErrorController extends AbstractErrorController {

 public AppErrorController(ErrorAttributes errorAttributes) {
  super(errorAttributes);
 }

 @RequestMapping
 public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
  Map<String, Object> body = getErrorAttributes(request, false);
  HttpStatus status = getStatus(request);
  // 返回响应体
  return new ResponseEntity<>(body, status);
 }

 @Override
 public String getErrorPath() {
  return "/error";
 }
}

如果没有配置 ErrorController, SpringBoot 会通过 ErrorMvcAutoConfiguration 自动配置一个,默认的实现类为 BasicErrorController。

ErrorController 可以处理非 @Controller 层抛出的异常,例如常见的访问了一个不存在的路径。

ErrorController 可以进行统一的错误处理,即让 HandlerExceptionResolver 返回的 ModelAndView 导向错误页面。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对小牛知识库的支持。

 类似资料:
  • 本文向大家介绍SpringMVC统一异常处理三种方法详解,包括了SpringMVC统一异常处理三种方法详解的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了SpringMVC-统一异常处理三种方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在 Spring MVC 应用的开发中,不管是对底层数据库操作,还是业务层或控制层操作,都

  • 本文向大家介绍深入剖析Java中的各种异常处理方式,包括了深入剖析Java中的各种异常处理方式的使用技巧和注意事项,需要的朋友参考一下 1. 调试追踪代码: 2. 抛出Exception,没有finally,当catch遇上return     后台输出结果: 3. 抛出Exception,当catch体里有return,finally体的代码块将在catch执行return之前被执行     后

  • 本文向大家介绍SpringMVC框架实现Handler处理器的三种写法,包括了SpringMVC框架实现Handler处理器的三种写法的使用技巧和注意事项,需要的朋友参考一下 一、SpringMVC中的处理器 配置完SpringMVC的处理器映射器,处理适配器,视图解析器后,需要手动写处理器。关于处理器的写法有三种,无论怎么写,执行流程都是①处理映射器通过@Controller注解找到处理器,继而

  • 本文向大家介绍JavaScript事件处理的方式(三种),包括了JavaScript事件处理的方式(三种)的使用技巧和注意事项,需要的朋友参考一下 最近这段时间因为每天要修改网站,为网站做特效,所以看了很多的js接触事件,自己只会使用一小部分,有时用的时候也比较混乱,现在系统的整理了一下,特此分享到呐喊教程平台供大家参考下! 一、什么是JavaScript事件? 事件(Event)是JavaScr

  • 本文向大家介绍浅谈RxJava处理业务异常的几种方式,包括了浅谈RxJava处理业务异常的几种方式的使用技巧和注意事项,需要的朋友参考一下 本文介绍了RxJava处理业务异常的几种方式,分享给大家。具体如下: 关于异常 Java的异常可以分为两种:运行时异常和检查性异常。 运行时异常: RuntimeException类及其子类都被称为运行时异常,这种异常的特点是Java编译器不去检查它,也就是说

  • 问题内容: 当在Java 8中使用FP习惯用法时,异常(尤其是经过检查的异常)会严重中断程序逻辑的流程。这是一个任意示例: 当无法解析的字符串存在异常时,以上代码将中断。但是说我只想用一个默认值替换它,就像我可以这样: 当然,这仍然会失败,因为仅处理s。我想要以下内容: 注意: 这是一个自我解答的问题。 问题答案: 下面显示的是该类的完整代码。它具有相当大的API,是对API 的纯扩展,因此可以在