SpringBoot 全局异常处理 + 参数校验,企业级规范写法(代码直接复制)
一、前言
在 SpringBoot 前后端分离项目里,这两个东西几乎是必写基础:
1.接口参数乱传,直接报错到前端
2.异常满天飞,前端各种无法解析
3.每个接口都写 try-catch,代码又臭又长
4.参数校验逻辑重复,维护成本极高
今天给你一套企业级标准方案:统一返回 + 全局异常处理 + 参数校验,一次写完,全项目通用,代码直接复制就能用。
二、引入依赖
<!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--参数校验--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>三、统一返回结果类 Result.java
importlombok.Data;@DatapublicclassResult<T>{privateIntegercode;privateStringmsg;privateTdata;publicstatic<T>Result<T>success(Tdata){Result<T>r=newResult<>();r.setCode(200);r.setMsg("操作成功");r.setData(data);returnr;}publicstatic<T>Result<T>success(){returnsuccess(null);}publicstatic<T>Result<T>error(Integercode,Stringmsg){Result<T>r=newResult<>();r.setCode(code);r.setMsg(msg);returnr;}publicstatic<T>Result<T>error(Stringmsg){returnerror(500,msg);}}四、实体类加参数校验注解
importlombok.Data;importjavax.validation.constraints.NotBlank;importjavax.validation.constraints.NotNull;importjavax.validation.constraints.Size;@DatapublicclassUser{privateLongid;@NotBlank(message="用户名不能为空")@Size(min=3,max=20,message="用户名长度3-20位")privateStringusername;@NotBlank(message="密码不能为空")@Size(min=6,max=20,message="密码长度6-20位")privateStringpassword;@NotNull(message="年龄不能为空")privateIntegerage;}五、自定义业务异常
publicclassBusinessExceptionextendsRuntimeException{privateIntegercode;publicBusinessException(Stringmessage){super(message);this.code=500;}publicBusinessException(Integercode,Stringmessage){super(message);this.code=code;}publicIntegergetCode(){returncode;}}六、全局异常处理器
importlombok.extern.slf4j.Slf4j;importorg.springframework.validation.BindException;importorg.springframework.validation.FieldError;importorg.springframework.web.bind.MethodArgumentNotValidException;importorg.springframework.web.bind.annotation.ExceptionHandler;importorg.springframework.web.bind.annotation.RestControllerAdvice;@RestControllerAdvice@Slf4jpublicclassGlobalExceptionHandler{/** * 校验异常 */@ExceptionHandler(MethodArgumentNotValidException.class)publicResult<?>handleValidException(MethodArgumentNotValidExceptione){FieldErrorfieldError=e.getBindingResult().getFieldError();Stringmsg=fieldError.getDefaultMessage();log.error("参数校验异常:{}",msg);returnResult.error(400,msg);}@ExceptionHandler(BindException.class)publicResult<?>handleBindException(BindExceptione){FieldErrorfieldError=e.getFieldError();Stringmsg=fieldError.getDefaultMessage();log.error("参数绑定异常:{}",msg);returnResult.error(400,msg);}/** * 自定义业务异常 */@ExceptionHandler(BusinessException.class)publicResult<?>handleBusinessException(BusinessExceptione){log.error("业务异常:{}",e.getMessage());returnResult.error(e.getCode(),e.getMessage());}/** * 系统异常 */@ExceptionHandler(Exception.class)publicResult<?>handleException(Exceptione){log.error("服务器异常",e);returnResult.error("服务器繁忙,请稍后重试");}}七、Controller 测试接口
importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestBody;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importjavax.validation.Valid;@RestController@RequestMapping("/user")publicclassUserController{@PostMapping("/add")publicResult<?>add(@Valid@RequestBodyUseruser){// 模拟业务异常if("admin".equals(user.getUsername())){thrownewBusinessException("该用户名已被占用");}returnResult.success("添加成功");}}八、效果演示
1. 参数为空返回
{"code":400,"msg":"用户名不能为空","data":null}2. 业务异常返回
{"code":500,"msg":"该用户名已被占用","data":null}3. 正常返回
{"code":200,"msg":"操作成功","data":"添加成功"}九、新手必看 4 个坑
忘了加 @Valid,校验不生效
必须在实体类前加 @Valid 才会触发校验。
GET 请求用 @RequestBody 报错
GET 没有请求体,参数校验用 @RequestParam + 校验注解。
异常信息暴露给前端
用全局异常统一包装,绝不返回堆栈信息。
自定义异常不生效确保类上有 @RestControllerAdvice 注解。
十、总结
这套代码是SpringBoot 项目标配:
所有异常统一处理
前端只需要解析一种格式
代码干净、规范、易维护
完全符合企业真实开发标准
不管是课设、毕设、还是实战项目,直接复制就能用。
十一、互动引导
你项目里还在用 try-catch 硬扛异常吗?评论区说说你踩过的异常坑,我帮你一起解决!
有用记得点赞 + 收藏,关注我,持续更新 Java 后端企业级实战内容!
