比如:当我们鉴权未登录时报错,我们可以给它返回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中无法捕获到异常,就无法处理。

Logo

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

更多推荐