1. 创建自定义异常类
public class ApproveException extends Exception {
public ApproveException() {
}
public ApproveException(String message) {
super(message);
}
}
public class HandleException extends Exception {
public HandleException() {
}
public HandleException(String message) {
super(message);
}
}
public class QueryException extends Exception {
public QueryException() {
}
public QueryException(String message) {
super(message);
}
}
2. 创建全局异常处理器
package jnpf.exception;
import cn.dev33.satoken.exception.IdTokenInvalidException;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import jnpf.base.ActionResult;
import jnpf.base.ActionResultCode;
import jnpf.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.List;
import java.util.Map;
@Slf4j
@RestController
@RestControllerAdvice
public class ResultException {
@ResponseBody
@ExceptionHandler(value = LoginException.class)
public ActionResult loginException(LoginException e) {
return ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
}
@ResponseBody
@ExceptionHandler(value = ImportException.class)
public ActionResult loginException(ImportException e) {
return ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
}
@ResponseBody
@ExceptionHandler(value = DataException.class)
public ActionResult dataException(DataException e) {
return ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
}
@ResponseBody
@ExceptionHandler(value = RuntimeException.class)
public ActionResult dataException(RuntimeException e) {
return ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
}
@ResponseBody
@ExceptionHandler(value = IllegalArgumentException.class)
public ActionResult dataException(IllegalArgumentException e) {
return ActionResult.fail(ActionResultCode.Fail.getCode(), e.getMessage());
}
@ResponseBody
@ExceptionHandler(value = WorkFlowException.class)
public ActionResult workFlowException(WorkFlowException e) {
if (e.getCode() == 200) {
List<Map<String, Object>> list = JsonUtil.getJsonToListMap(e.getMessage());
return ActionResult.success(list);
} else {
return ActionResult.fail(e.getMessage());
}
}
@ResponseBody
@ExceptionHandler(value = WxErrorException.class)
public ActionResult wxErrorException(WxErrorException e) {
return ActionResult.fail(e.getError().getErrorCode(), "操作过于频繁");
}
@ResponseBody
@ExceptionHandler(NotPermissionException.class)
public ActionResult<Void> handleNotPermissionException(NotPermissionException e) {
return ActionResult.fail(ActionResultCode.Fail.getCode(), "没有访问权限,请联系管理员授权");
}
@ResponseBody
@ExceptionHandler(NotRoleException.class)
public ActionResult<Void> handleNotRoleException(NotRoleException e) {
return ActionResult.fail(ActionResultCode.ValidateError.getCode(), "没有访问权限,请联系管理员授权");
}
@ResponseBody
@ExceptionHandler(NotLoginException.class)
public ActionResult<Void> handleNotLoginException(NotLoginException e) {
return ActionResult.fail(ActionResultCode.SessionOverdue.getCode(), "认证失败,无法访问系统资源");
}
@ResponseBody
@ExceptionHandler(IdTokenInvalidException.class)
public ActionResult<Void> handleIdTokenInvalidException(IdTokenInvalidException e) {
return ActionResult.fail(ActionResultCode.SessionOverdue.getCode(), "无效内部认证,无法访问系统资源");
}
}
3. 创建统一错误响应体
package jnpf.base;
import com.fasterxml.jackson.annotation.JsonInclude;
import jnpf.base.vo.PageListVO;
import jnpf.base.vo.PaginationVO;
import jnpf.constant.MsgCode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ActionResult<T> {
@Schema(description = "状态码")
private Integer code;
@Schema(description = "返回信息")
private String msg;
@Schema(description = "返回数据")
private T data;
public static <T> ActionResult<T> success() {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setCode(200);
jsonData.setMsg(MsgCode.SU000.get());
return jsonData;
}
public static <T> ActionResult<T> success(String msg) {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setCode(200);
jsonData.setMsg(msg);
return jsonData;
}
public static <T> ActionResult<T> success(T object) {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setData(object);
jsonData.setCode(200);
jsonData.setMsg(MsgCode.SU000.get());
return jsonData;
}
public static <T> ActionResult<T> success(String msg, T object) {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setData(object);
jsonData.setCode(200);
jsonData.setMsg(msg);
return jsonData;
}
public static <T> ActionResult<T> fail(Integer code, String message) {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setCode(code);
jsonData.setMsg(message);
return jsonData;
}
public static ActionResult<String> fail(String msg, String data) {
ActionResult<String> jsonData = new ActionResult<>();
jsonData.setMsg(msg);
jsonData.setData(data);
return jsonData;
}
public static <T> ActionResult<T> fail(String msg) {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setMsg(msg);
jsonData.setCode(400);
return jsonData;
}
public static <T> ActionResult<PageListVO<T>> page(List<T> list, PaginationVO pagination) {
ActionResult<PageListVO<T>> jsonData = new ActionResult<>();
PageListVO<T> vo = new PageListVO<>();
vo.setList(list);
vo.setPagination(pagination);
jsonData.setData(vo);
jsonData.setCode(200);
jsonData.setMsg(MsgCode.SU000.get());
return jsonData;
}
public static <T> ActionResult<DataInterfacePageListVO<T>> page(List<T> list, PaginationVO pagination, String dataProcessing) {
ActionResult<DataInterfacePageListVO<T>> jsonData = new ActionResult<>();
DataInterfacePageListVO<T> vo = new DataInterfacePageListVO<>();
vo.setList(list);
vo.setPagination(pagination);
vo.setDataProcessing(dataProcessing);
jsonData.setCode(200);
jsonData.setData(vo);
jsonData.setMsg(MsgCode.SU000.get());
return jsonData;
}
}
4. 异常错误提示枚举
public enum ActionResultCode {
/**
* 成功
*/
Success(200, "成功"),
/**
* 失败
*/
Fail(400, "失败"),
/**
* 验证错误
*/
ValidateError(401, "验证错误"),
/**
* 异常
*/
Exception(500, "异常"),
/**
* 登录过期提示
*/
SessionOverdue(600, "登录过期,请重新登录"),
/**
* 踢出提示
*/
SessionOffLine(601, "您的帐号在其他地方已登录,被强制踢出"),
/**
* token失效
*/
SessionError(602, "Token验证失败");
private int code;
private String message;
ActionResultCode(int code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
关键点说明:
@ControllerAdvice
:标记为全局异常处理器@ExceptionHandler
:指定处理的异常类型响应实体:使用
ActionResult
可自定义HTTP状态码异常优先级:Spring会匹配最具体的异常处理器
错误信息:包含时间戳、错误码、消息和请求路径
这样实现的全局异常处理器具有以下优点:
统一处理控制器层所有异常
支持自定义异常类型和错误码
返回结构化的错误信息
分离业务逻辑与错误处理
支持HTTP状态码动态设置
易于扩展和维护