目录
1.定义全局统一返回类用作给前端返回格式
2.定义全局返回类状态枚举
3.继承RuntimeException异常进行重写
4.定义全局异常处理类
5.定义测试控制器进行测试
本文记录下对全局异常处理和统一返回类的处理,在程序中返回格式统一规范对于前端和后端的开发都是提供了很多便利。下面记录下全局异常处理和统一返回类。以下部分代码不是固定这样操作的,是方便程序处理的。
1.定义全局统一返回类用作给前端返回格式
@Data注解省略get()和set()方法。@Apixxxxxx注解为Swagger注解
定义统一返回类将返回给前端的格式统一为
{
"code": 10000,
"msg": "操作成功",
"data": null
}
方便前端和后端操作
package com.example.hecen.common.util;
import com.example.hecen.common.enums.ResultCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "统一返回实体")
public class ResultData<T> implements Serializable {
@ApiModelProperty("统一响应编码")
private int code;
@ApiModelProperty("统一响应信息")
private String msg;
@ApiModelProperty("统一响应数据")
private T data;
public static <T> ResultData<T> success(){
ResultData<T> resultData=new ResultData<T>();
resultData.setMsg("操作成功");
resultData.setCode(ResultCodeEnum.SUCCESS.getCode());
return resultData;
}
public static <T> ResultData<T> success(String msg){
ResultData<T> resultData=new ResultData<T>();
resultData.setMsg(msg);
resultData.setCode(ResultCodeEnum.SUCCESS.getCode());
return resultData;
}
public static <T> ResultData<T> success(T data){
ResultData<T> resultData=new ResultData<T>();
resultData.setData(data);
resultData.setMsg("操作成功");
resultData.setCode(ResultCodeEnum.SUCCESS.getCode());
return resultData;
}
public static <T> ResultData<T> success(T data,String msg){
ResultData<T> resultData=new ResultData<T>();
resultData.setData(data);
resultData.setMsg(msg);
resultData.setCode(ResultCodeEnum.SUCCESS.getCode());
return resultData;
}
/**
* @Description:
*/
public static <T> ResultData<T> error() {
ResultData<T> resultData = new ResultData<>();
resultData.setCode(ResultCodeEnum.FAILED.getCode());
resultData.setMsg("系统异常");
return resultData;
}
/**
* @Description:
*/
public static <T> ResultData<T> error(String msg) {
ResultData<T> resultData = new ResultData<>();
resultData.setCode(ResultCodeEnum.FAILED.getCode());
resultData.setMsg(msg);
return resultData;
}
/**
* @Description:
*/
public static <T> ResultData<T> error(int code,String msg) {
ResultData<T> resultData = new ResultData<>();
resultData.setCode(code);
resultData.setMsg(msg);
return resultData;
}
}
2.定义全局返回类状态枚举
定义每种code对于的信息,如10000对于请求成功,将code和msg写入统一返回类的标准,赋值通过枚举的调用
package com.example.hecen.common.enums;
/**
* 返回状态枚举
*/
public enum ResultCodeEnum {
SUCCESS(10000, "请求成功"),
FAILED(10001, "操作失败"),
TOKEN_FAILED(10002, "操作超时"),
NO_PERMISSION(10003, "无权限"),
LOGOUT(10004, "已退出"),
SAFE_CHECK_FAILED(30002, "此操作需要先进行安全验证"),
NONE(99999, "无");
private int code;
private String msg;
private ResultCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
3.继承RuntimeException异常进行重写
RuntimeException为运行时异常,对异常分类不了解的可以搜索了解下,也可以继承别的异常进行重写。
package com.example.hecen.common.exception;
import com.example.hecen.common.enums.ResultCodeEnum;
import lombok.Data;
/**
* 继承Runtime异常
*/
@Data
public class ResultException extends RuntimeException {
private Integer code;
private String msg;
public ResultException(String msg){
this.msg=msg;
}
public ResultException(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public ResultException(ResultCodeEnum resultCode) {
this.code = resultCode.getCode();
this.msg = resultCode.getMsg();
}
public ResultException(Throwable cause) {
super(cause);
}
}
4.定义全局异常处理类
当程序出现某些异常将通过下列方法进行返回。实现是通过@ControllerAdvice和@ExceptionHandler(value = "异常类")注解来配合实现的,当程序中出现@ExceptionHandler使用的异常类抛出异常屎,就会进入下列对应的方法中进行操作(这里定义为按统一返回类进行返回)。
@ControllerAdvice注解还能和@InitBinder或者@ModelAttribute进行配合使用,具体使用方式想了解的小伙伴可以搜索下
package com.example.hecen.config;
import com.example.hecen.common.exception.ResultException;
import com.example.hecen.common.util.ResultData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/**
* 全局异常配置
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(value = Exception.class)
public ResultData<String> exceptionHandler(HttpServletRequest httpServletRequest, Exception e) {
String erroMsg = String.format("来至 %s 的请求发生以下错误", httpServletRequest.getRequestURL());
log.error(erroMsg, e);
return ResultData.error("内部错误");
}
@ResponseBody
@ExceptionHandler(value = IllegalArgumentException.class)
public ResultData<String> IllegalArgumentException(HttpServletRequest httpServletRequest, Exception e) {
String erroMsg = String.format("来至 %s 的请求发生以下错误", httpServletRequest.getRequestURL());
log.error(erroMsg, e);
return ResultData.error(e.getMessage());
}
@ResponseBody
@ExceptionHandler(value = ResultException.class)
public ResultData<String> businessExceptionHandler(HttpServletRequest httpServletRequest, ResultException e) {
String erroMsg = String.format("来至 %s 的请求发生以下错误", httpServletRequest.getRequestURL());
log.error(erroMsg, e);
// if (e.getCode() == ResultCodeEnum.TOKEN_FAILED.getCode()) {
// return ResultData.tokenFailed(e.getMsg());
// }
return ResultData.error(e.getMsg());
}
}
5.定义测试控制器进行测试
package com.example.hecen.controller;
import com.example.hecen.common.exception.ResultException;
import com.example.hecen.common.util.ResultData;
import com.example.hecen.entity.User;
import com.example.hecen.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "标准服务信息")
@RestController
@RequestMapping("/user")
public class UserController {
@ApiOperation(value = "异常1")
@PostMapping("/info/test1")
public ResultData<String> test1() {
return ResultData.success();
}
@ApiOperation(value = "异常2")
@PostMapping("/info/test2")
public ResultData<String> test2() {
if(0==0){
throw new ResultException("测试异常");
}
return ResultData.success();
}
@ApiOperation(value = "异常3")
@PostMapping("/info/test3")
public ResultData<String> test3() {
int i=0;
int z=i/0;
return ResultData.success();
}
}
可以看到返回都是这种格式。