欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringMVC 三种异常处理方式

程序员文章站 2022-05-20 22:47:15
SpringMVC 三种异常处理方式 在 SpringMVC, SpringBoot 处理 web 请求时, 若遇到错误或者异常,返回给用户一个良好的错误信息比 Whitelabel Error Page 好的多。 SpringMVC 提供了三种异常处理方式, 良好的运用它们可以给用户提供可读的错误 ......

springmvc 三种异常处理方式

在 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 导向错误页面。