SpringBoot异常控制处理

Spring boot 处理 error 的基本流程:

Controller -> 发生错误 -> BasicErrorController -> 根据 @RequestMapping(produces) 判断调用 errorHtml 或者 error 方法

然后:

errorHtml -> getErrorAttributes -> ErrorViewResolver -> 错误显示页面

error -> getErrorAttributes -> @ResponseBody (直接返回JSON)

如果想要定制一些东西,按照官方文档的建议可以:

1.继承 BasicErrorController  扩展处理一个新的 content type

2.自定义 ErrorAttributes 获得自己想要的结果集

3.实现 ErrorViewResolver 接口,自定义错误显示视图

Spring boot 默认使用 DefaultErrorViewResolver 作为 ErrorViewResolver  的实现,并配置了 4xx, 5xx 视图

一般的,并不需要扩展上面的内容,通常情况下,下面两种方式可以应对大部分场景

注意:如 404 等是通过 Servlet (DispatcherServlet.noHandlerFound) 的处理并返回 response ( response.sendError) ,并未到达 Controller 层,所以并不能捕获到。

1.捕获异常:

使用 @ControllerAdvice 与 @ExceptionHandler 捕获异常并处理(返回自定义json对象或是页面视图,将替代 ErrorAttributes、ErrorViewResolver)

2.直接提供相应错误显示视图

一、使用@ControllerAdvice

此方式只会处理Controller异常,其它异常仍会用SpringBoot默认异常处理方式。@RestControllerAdvice返回json

/**
 * 全局异常,类似spring处理
 * @author WANGJS-PC
 *
 */
@ControllerAdvice
public class GlobalDefaultExceptionHandler {
    /**
     * 处理 Exception 类型的异常
     * 方法名为任意名,入参一般使用 Exception 异常类,方法返回值可自定义。
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Map<String, Object> defaultExceptionHandler(Exception e) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", 500);
        map.put("msg", e.getMessage());
        return map;
    }

二、

      在templates下新建error文件夹,新建404,400等html,遇到此错误会自动跳转到此html。

默认会从templates、static、public下依次寻找。

三、继承BasicErrorController

      也可以继承AbstractErrorController,仿照BasicErrorController重写此类。BasicErrorController是SpringBoot提供的一个处理异常的类。可以继承他扩展,也可以自己完全重写。

关键的两个方法:

public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        HttpStatus status = getStatus(request);
        Map<String, Object> model = Collections
                .unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = resolveErrorView(request, response, status, model);
        return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);
    }

    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
        HttpStatus status = getStatus(request);
        return new ResponseEntity<Map<String, Object>>(body, status);

    }

可以根据状态码返回内容。重写此类注册到容器中(添加@Component或@Controller即可),二会失效,不会自动跳转html。

四、自定义异常处理路径 ErrorPageRegistry

/**

     * 自定义异常处理路径 ErrorPageRegistry
     *
     * @return
     */
    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return new EmbeddedServletContainerCustomizer() {
            @Override
            public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {

                configurableEmbeddedServletContainer.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,

                                                                                                                                    "/test/1234"));

                configurableEmbeddedServletContainer.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST,

                                                                                                                                   "/test/400"));

                configurableEmbeddedServletContainer.addErrorPages(new ErrorPage(

                                                                                               HttpStatus.INTERNAL_SERVER_ERROR,"/test/500"));

                configurableEmbeddedServletContainer.addErrorPages(new ErrorPage(

                                                                                               java.lang.Throwable.class, "/test/500"));

            }
        };

    }

注册这个bean(二也会失效),然后添加相应Controller即可。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值