微服务-gateway全局异常处理
·
比如:当我们鉴权未登录时报错,我们可以给它返回code值为401,然后前端可以根据401编码,跳转到登录页面


1,首先要将统一返回结果复制到gateway微服务模块下,即将下面两个类放入gateway建好的entity和enums包中。

package com.qiao.entity;
import com.qiao.enums.ResultCodeEnum;
import lombok.Data;
/**
* 统一返回结果
*/
@Data
public class Result<T> {
private Boolean success;
private Integer code;
private String message;
private T data;
//没有参数的成功返回
public static Result ok() {
Result result = new Result();
result.setSuccess(true);
result.setCode(ResultCodeEnum.SUCCESS.getCode());
result.setMessage(ResultCodeEnum.SUCCESS.getDesc());
return result;
}
//有参数的成功返回
public static<T> Result ok(T data) {
Result result = new Result();
result.setSuccess(true);
result.setCode(ResultCodeEnum.SUCCESS.getCode());
result.setMessage(ResultCodeEnum.SUCCESS.getDesc());
result.setData(data);
return result;
}
//没有参数的成功失败
public static Result fail() {
Result result = new Result();
result.setSuccess(false);
result.setCode(ResultCodeEnum.FAIL.getCode());
result.setMessage(ResultCodeEnum.FAIL.getDesc());
return result;
}
//有参数的成功返回
public static<T> Result fail(T data) {
Result result = new Result();
result.setSuccess(false);
result.setCode(ResultCodeEnum.FAIL.getCode());
result.setMessage(ResultCodeEnum.FAIL.getDesc());
result.setData(data);
return result;
}
//gateway全局异常处理的返回
public static Result fail(Integer code,String message) {
Result result = new Result();
result.setSuccess(false);
result.setCode(code);
result.setMessage(message);
return result;
}
}
package com.qiao.enums;
import lombok.Getter;
/**
* 自定义枚举响应码
*/
@Getter
public enum ResultCodeEnum {
SUCCESS(200, "操作成功"),
FAIL(500,"操作失败");
public int code;
public String desc;
ResultCodeEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
// 根据code获取枚举
public static ResultCodeEnum getByCode(int codeVal) {
for (ResultCodeEnum resultCodeEnum : ResultCodeEnum.values()) {
if (resultCodeEnum.getCode() == codeVal) {
return resultCodeEnum;
}
}
return null;
}
}
2,在gateway中创建一个包exception,然后在这个包下创建一个类GatewayExceptionHandler去继承ErrorWebExceptionHandler,同时添加Component注解,将其放入spring容器中。
这里我只做了两个处理,如果是鉴权satoken异常则抛出401,如果是其他系统异常直接抛500
package com.qiao.exception;
import cn.dev33.satoken.exception.SaTokenException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qiao.entity.Result;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 网关全局异常处理
*/
@Component
public class GatewayExceptionHandler implements ErrorWebExceptionHandler {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public Mono<Void> handle(ServerWebExchange serverWebExchange, Throwable throwable) {
ServerHttpRequest request = serverWebExchange.getRequest();// 请求
ServerHttpResponse response = serverWebExchange.getResponse();// 响应
Integer code = 200;
String message = "";
if (throwable instanceof SaTokenException){// 如果是鉴权抛出的异常
code = 401;
message = "用户无权限!";
}else{// 如果是系统抛出的异常
code = 500;
message = "系统异常!";
}
Result result = Result.fail(code, message);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
return response.writeWith(Mono.fromSupplier(() -> {
DataBufferFactory dataBufferFactory = response.bufferFactory();
byte[] bytes = null;
try {
bytes = objectMapper.writeValueAsBytes(result);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return dataBufferFactory.wrap(bytes);
}));
}
}
3,同时我们需要将SaTokenConfigure中后面的异常处理注释掉,不然在GatewayExceptionHandler中无法捕获到异常,就无法处理。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)