如何使用 Spring Boot 实现异常处理?

这些是 Spring Boot 处理异常 的几种方式。我们来逐步拆解,看懂每种方式的用途和区别。


1、@ExceptionHandler 处理局部异常

这是最简单的方式,在 当前 Controller 内 处理异常。

@Controller
public class ExceptionHandlerController {

    @RequestMapping("/excep")
    public String exceptionMethod(Model model) throws Exception {
        String a = null;
        System.out.println(a.charAt(1)); // NullPointerException
        int num = 1 / 0; // ArithmeticException
        model.addAttribute("message", "没有抛出异常");
        return "index";
    }

    @ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class})
    public String arithmeticExceptionHandle(Model model, Exception e) {
        model.addAttribute("message", "@ExceptionHandler 处理的异常:" + e.getMessage());
        return "index";
    }
}

重点

  1. @ExceptionHandler 用来捕获指定类型的异常(这里只能处理 ArithmeticExceptionNullPointerException)。
  2. 仅限当前 Controller 内,其他 Controller 发生异常不会被这个方法处理。
  3. 处理完异常后,返回一个指定的视图(这里返回 "index" 页面)。

2、@ControllerAdvice + @ExceptionHandler 处理全局异常

上面的 @ExceptionHandler 只能处理单个 Controller 内的异常,如果想要在全局范围内处理异常,就可以用 @ControllerAdvice

@ControllerAdvice
public class ControllerAdviceException {

    @ExceptionHandler(value = {NullPointerException.class})
    public String NullPointerExceptionHandler(Model model, Exception e) {
        model.addAttribute("message", "@ControllerAdvice + @ExceptionHandler 处理的异常:" + e.getMessage());
        return "index";
    }
}

重点

  1. @ControllerAdvice 作用于所有 Controller,可以统一处理全局异常。
  2. @ExceptionHandler(value = {NullPointerException.class}) 只捕获 NullPointerException
  3. 发生异常后,会跳转到 "index" 页面,并在 model 里添加异常信息。

3、使用 SimpleMappingExceptionResolver 统一映射异常

前面两种方式是通过 方法 处理异常,这种方式是通过配置来映射异常到页面。

@Configuration
public class SimpleMappingException {

    @Bean
    public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();

        // 定义异常和页面的映射关系
        mappings.put("java.lang.NullPointerException", "index");
        mappings.put("java.lang.ArithmeticException", "index");

        resolver.setExceptionMappings(mappings); // 设置异常映射
        return resolver;
    }
}

重点

  1. 自动匹配异常NullPointerExceptionArithmeticException 发生时,直接跳转 "index" 页面。
  2. 不需要手动写 @ExceptionHandler 方法,通过配置 Properties 直接映射。

适合场景

  • 只需要简单页面跳转,不需要动态返回错误信息。

4、实现 HandlerExceptionResolver 处理异常

如果想要更灵活地控制异常处理逻辑,可以实现 HandlerExceptionResolver 接口。

@Configuration
public class HandlerException implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("message", "HandlerExceptionResolver 处理的异常");

        // 根据异常类型,跳转到不同的页面
        if (ex instanceof NullPointerException) {
            modelAndView.setViewName("index");
        }
        if (ex instanceof ArithmeticException) {
            modelAndView.setViewName("index");
        }

        return modelAndView;
    }
}

重点

  1. SimpleMappingExceptionResolver 更灵活,可以对不同异常执行不同的逻辑。
  2. 可以修改 HTTP 响应状态,比如 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
  3. 适用于复杂的异常处理需求,比如:
    • 记录日志
    • 返回不同的错误页面
    • 发送错误信息到前端 API

总结

方式 作用范围 适用场景 缺点
@ExceptionHandler 只能处理当前 Controller 的异常 处理局部异常,简单的 Controller 级异常处理 只能用于当前 Controller,无法全局使用
@ControllerAdvice + @ExceptionHandler 作用于所有 Controller 处理全局异常,适用于统一异常处理 需要写多个方法分别处理不同的异常
SimpleMappingExceptionResolver 作用于全局 仅用于异常 → 页面跳转,适用于简单场景 不能自定义返回 JSON 响应,无法进行复杂异常处理
HandlerExceptionResolver 作用于全局 需要灵活处理异常,如记录日志、返回 JSON、跳转不同页面等 需要手动编写逻辑

如果是 Spring Boot + 前后端分离的项目,一般会用 @ControllerAdvice + @ExceptionHandler 返回 JSON 格式的错误信息,比如:

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(NullPointerException.class)
    public ResponseEntity handleNullPointerException(Exception e) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("发生空指针异常:" + e.getMessage());
    }

    @ExceptionHandler(ArithmeticException.class)
    public ResponseEntity handleArithmeticException(Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("发生算术异常:" + e.getMessage());
    }
}

最佳实践

  1. 前后端分离项目,推荐使用 @ControllerAdvice + @ExceptionHandler 返回 JSON
  2. 后端渲染页面(如 Thymeleaf),可以用 SimpleMappingExceptionResolver 简单映射异常到错误页面。
  3. 需要复杂逻辑(比如日志、发送邮件通知),可以用 HandlerExceptionResolver 自定义处理

你可能感兴趣的:(面试,前端,java,python)