springboot怎么返回404_Springboot项目统一异常处理

本文介绍了在Springboot项目中如何进行统一异常处理,包括定义Result对象作为通用返回结果封装,创建GlobalException作为全局异常信息,设置异常处理类@RestControllerAdvice,以及处理404异常的方法,确保404错误能够被正确捕获并展示自定义错误页面。
摘要由CSDN通过智能技术生成

Springboot项目统一异常处理

一.接口返回值封装

基于目前大多数项目都采用前后端分离架构,所以后端接口统一返回值封装是比较重要的,便于前后端对接与统一处理。当然按各自项目约定实现即可,思路大同小异,下面是我的实现方式,仅供参考

1. 定义Result对象,作为通用返回结果封装

/**

*

@filename Result

*

*

@description 通用返回结果封装

*

* @author llspace

* @version 1.0

* @since 2019/6/17 11:55

**/

@Data

public class Result {

private int code;

private String msg;

private T data;

/**

* 成功时候的调用

*/

public static Result success(T data) {

return new Result(data);

}

/**

* 失败时候的调用

*/

public static Result error(CodeMsg cm) {

return new Result(cm);

}

private Result(T data) {

this.code = 0;

this.msg = "success";

this.data = data;

}

private Result(CodeMsg cm) {

if (cm == null) {

return;

}

this.code = cm.getCode();

this.msg = cm.getMsg();

}

}

2. 定义CodeMsg对象,作为通用状态码和消息封装

/** * 

@filename CodeMsg

*

*

@description 通用状态码和消息封装

* * @author llspace * @version 1.0 * @since 2019/6/17 11:57 **/@Datapublic class CodeMsg { //自定义状态码 private int code; //消息信息 private String msg; //通用异常 4001XX public static CodeMsg SUCCESS = new CodeMsg(0, "success"); public static CodeMsg SERVER_ERROR = new CodeMsg(500100, "服务端异常"); //模块1 4002XX //模块2 4003XX //模块3 4004XX private CodeMsg(int code, String msg) { this.code = code; this.msg = msg; } public CodeMsg fillArgs(Object... args) { int code = this.code; String message = String.format(this.msg, args); return new CodeMsg(code, message); }}

二.定义全局异常类

基于上面封装的CodeMsg实现GlobalException定义,异常继承RuntimeException

/**

*

@filename GlobalException

*

*

@description 全局异常信息

*

* @author llspace

* @version 1.0

* @since 2019/6/20 18:05

**/

@Data

public class GlobalException extends RuntimeException {

private static final long serialVersionUID = 1L;

private CodeMsg codeMsg;

public GlobalException(CodeMsg codeMsg) {

super(codeMsg.toString());

this.codeMsg = codeMsg;

}

}

三.定义异常处理类

@RestControllerAdvice作用等同于@ResponseBody加上@ControllerAdvice,会在所有带有@Controller或者@RestController注解的类上生效,还可以使用basePackages参数配置指定异常处理类生效的包

/** * 

@filename GlobalExceptionHandler

*

*

@description 全局异常处理类

* * @author llspace * @version 1.0 * @since 2019/6/20 18:07 **/@RestControllerAdvicepublic class GlobalExceptionHandler { @ExceptionHandler(value = Exception.class) public Result exceptionHandler(HttpServletRequest request, Exception e){ e.printStackTrace(); if(e instanceof GlobalException) { GlobalException exception = (GlobalException) e; return Result.error(exception.getCodeMsg()); }else if(e instanceof BindException) { BindException ex = (BindException) e; List errors = ex.getAllErrors(); ObjectError error = errors.get(0); String msg = error.getDefaultMessage(); return Result.error(CodeMsg.BIND_ERROR.fillArgs(msg)); }else { return Result.error(CodeMsg.SERVER_ERROR); } }}

四.特殊处理404异常

spring boot默认不会抛出404异常(NoHandlerFoundException),所以在ControllerAdvice中捕获不到该异常,导致404总是跳过ContollerAdvice,直接显示ErrorController的错误页。需要改变配置,让404错误抛出异常(NoHandlerFoundException),这样便可在ControllerAdvice中捕获此异常。

如果是restful项目改变配置即可实现捕获上述异常,在application.yml中添加:

spring: mvc: throw-exception-if-no-handler-found: true resources:  add-mappings: false

注意:添加了如上配置会造成项目静态资源访问异常, 如果不是restful的项目这样配置就会有问题,所以就需要采用其他方式来处理了, 可以参考如下处理方法

如果是带静态资源的项目我们要如何来处理404异常呢?

断点下BasicErrorController类,查看下源码可知,errorHtml()方法默认会返回一个new ModelAndView(“error”, model),所以其实在classpath:/templates下自定义一个error.html即可,这样springboot默认的404错误就跳转到了自己项目下的error页面了,这种处理比较简单,如果想更好的封装错误页面,建议自己实现ErrorController接口,或者继承AbstractErrorController / BasicErrorController类来实现,当然前提是删除掉配置文件中上述的两个配置。

五 . 测试使用效果

至此,统一异常处理就实现了,如下使用,

if(loginVO == null) { throw new GlobalException(CodeMsg.SERVER_ERROR);}

这样会抛出异常如下:

GlobalException(codeMsg=CodeMsg(code=500100, msg=服务端异常))

如果是404异常会跳项目自定义的error页面

dd1f14d590bdcf4a5460a36206e6fc37.png

个人实现,仅供参考,有兴趣的小伙伴自己动手尝试吧!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值