java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring MVC处理异常

详解Spring MVC优雅处理异常的6种方式

作者:猿java

在Spring中提供了多种机制来处理控制器抛出的异常,确保应用程序在面对各种错误情况时能够优雅地响应,本文我们来详细分析Spring MVC中6种优雅处理异常的方式,需要的可以参考下

异常处理是每个 Java程序员需要面对的一个问题,在Spring中,提供了多种机制来处理控制器抛出的异常,确保应用程序在面对各种错误情况时能够优雅地响应。这篇文章,我们来详细分析Spring MVC中,几种优雅处理异常的方式。

1. 使用@ExceptionHandler注解

@ExceptionHandler注解允许在单个Controller中定义处理特定异常的方法。当 Controller的方法抛出指定的异常时,Spring会调用相应的处理方法。

如下示例,展示了如何在 Controller层优雅处理异常:

@Controller
public class MyController {

    @RequestMapping("/example")
    public String example() {
        // 可能抛出异常的业务逻辑
        if (1/0) {
            throw new CustomException("自定义异常发生");
        }
        return "success";
    }

    @ExceptionHandler(CustomException.class)
    public ModelAndView handleCustomException(CustomException ex) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("message", ex.getMessage());
        mav.setViewName("errorPage");
        return mav;
    }
}

优点: 简单直观,适用于单个控制器的异常处理。

缺点: 如果多个控制器需要相同的异常处理逻辑,需要在每个控制器中重复定义。

2. 使用@ControllerAdvice注解

@ControllerAdvice是一种全局的异常处理方式,可以应用于所有 Controller。通过将异常处理逻辑集中在一个地方,可以避免代码重复,提高维护性。

如下示例,展示了如何使用@ControllerAdvice优雅处理全局异常:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(CustomException.class)
    public ModelAndView handleCustomException(CustomException ex) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("message", ex.getMessage());
        mav.setViewName("errorPage");
        return mav;
    }

    @ExceptionHandler(Exception.class)
    public ModelAndView handleGeneralException(Exception ex) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("message", "发生了一个错误: " + ex.getMessage());
        mav.setViewName("errorPage");
        return mav;
    }
}

优点:

缺点:

3. 实现HandlerExceptionResolver接口

HandlerExceptionResolver 是一种更底层的异常处理机制,通过实现该接口,开发者可以自定义异常解析逻辑。

如下示例,展示了如何实现HandlerExceptionResolver接口优雅处理异常:

public class MyExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response,
                                         Object handler,
                                         Exception ex) {
        ModelAndView mav = new ModelAndView();
        if (ex instanceof CustomException) {
            mav.addObject("message", ex.getMessage());
            mav.setViewName("customErrorPage");
        } else {
            mav.addObject("message", "未知错误");
            mav.setViewName("errorPage");
        }
        return mav;
    }
}

配置:

在 Spring 配置文件中注册自定义异常解析器:

<bean class="com.example.MyExceptionResolver"/>

优点:

高度灵活,可以处理各种复杂的异常情景。

缺点:

4. 使用@ResponseStatus注解

@ResponseStatus注解可以用于自定义异常对应的 HTTP 状态码和错误信息,当抛出带有该注解的异常时,Spring会自动设置相应的状态码。

如下示例,展示了如何使用@ResponseStatus注解优雅处理异常:

@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "资源未找到")
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

使用:

@Controller
public class MyController {

    @RequestMapping("/resource")
    public String getResource() {
        // 假设资源未找到
        throw new ResourceNotFoundException("资源ID不存在");
    }
}

优点:

简单快捷,适用于直接映射到特定 HTTP 状态码的异常情况。

缺点:

无法返回自定义的错误页面或更复杂的错误信息。

5. 使用ResponseEntity和@RestControllerAdvice

在构建 RESTful API时,常用ResponseEntity来返回自定义的错误响应,并结合@RestControllerAdvice可以全局处理异常并返回 JSON 格式的错误信息。

如下示例,展示了如何使用ResponseEntity@RestControllerAdvice来处理 RESTful API的异常:

@RestControllerAdvice
public class RestExceptionHandler {

    @ExceptionHandler(CustomException.class)
    public ResponseEntity<ErrorResponse> handleCustomException(CustomException ex) {
        ErrorResponse error = new ErrorResponse("CUSTOM_ERROR", ex.getMessage());
        return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) {
        ErrorResponse error = new ErrorResponse("GENERAL_ERROR", "内部服务器错误");
        return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

public class ErrorResponse {
    private String errorCode;
    private String errorMessage;

    // 构造方法、getter 和 setter
}

优点:

缺点:

需要定义额外的错误响应类。

6. 使用@ControllerAdvice和@ExceptionHandler

如果使用 Spring Boot,可以更便捷地使用 @ControllerAdvice 结合自动配置实现异常处理。

如下示例,展示了如何使用@ControllerAdvice@ExceptionHandler来处理异常:

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ValidationErrorResponse> handleValidationExceptions(
            MethodArgumentNotValidException ex) {
        ValidationErrorResponse errors = new ValidationErrorResponse();
        ex.getBindingResult().getAllErrors().forEach((error) -> {
            errors.addError(((FieldError) error).getField(), error.getDefaultMessage());
        });
        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }

    // 其它异常处理方法
}

优点:

7. 总结

本文,我们分析了 Spring MVC优雅处理异常的几种方法以及代码示例,我们可以根据具体需求选择合适的方法:

从实际工作来看,@ControllerAdvice@RestControllerAdvice是使用频率最高的一种方式。

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

您可能感兴趣的文章:
阅读全文