spring boot实现Grpc全局异常捕获返回

版权说明: 本文由博主keep丶原创,转载请注明出处。
原文地址: https://blog.csdn.net/qq_38688267/article/details/120787954

前言

  作者有一个项目中考虑到性能和跨平台能力,采用Grpc作为服务间调度的方案,但是Grpc对JAVA的支持太差,使用起来比较麻烦,为了简化部分代码,作者封装了Grpc的全局异常捕获功能。

代码

服务端

@GrpcGlobalServerInterceptor
public class GrpcServerInterceptor implements ServerInterceptor {

    @Override
    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall,
                                                                 Metadata metadata,
                                                                 ServerCallHandler<ReqT, RespT> serverCallHandler) {
        return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(serverCallHandler.startCall(serverCall, metadata)) {
            @Override
            public void onHalfClose() {
                try {
                    super.onHalfClose();
                } catch (Exception e) {
                    if (!(e instanceof BusinessException)) {
                        e.printStackTrace();
                    }
                    // 通过元数据传输消息
                    metadata.put(Metadata.Key.of("message-bin", new Metadata.BinaryMarshaller<String>() {
                        @Override
                        public byte[] toBytes(String value) {
                            return value.getBytes(StandardCharsets.UTF_8);
                        }

                        @Override
                        public String parseBytes(byte[] serialized) {
                            return new String(serialized);
                        }
                    }), e.getMessage());
                    serverCall.close(Status.INVALID_ARGUMENT, metadata);
                }
            }
        };
    }
}

客户端

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    /**
     * Grpc远程调用异常处理
     */
    @ExceptionHandler(StatusRuntimeException.class)
    public ResponseMessage statusRuntimeException(StatusRuntimeException e) {
        Metadata metadata = e.getTrailers();
        // 这里可以细化到根据状态确定返回值
        if (e.getStatus().getCode().value() == Status.INVALID_ARGUMENT.getCode().value()) {
        }
        // 这里的message-bin,要跟服务端返回的值一致
        return new ResponseMessage(Constant.ERROR_CODE, metadata.get(Metadata.Key.of("message-bin", new MyBinaryMarshaller())));
    }

    private static class MyBinaryMarshaller implements Metadata.BinaryMarshaller<String> {

        @Override
        public byte[] toBytes(String value) {
            return value.getBytes(StandardCharsets.UTF_8);
        }

        @Override
        public String parseBytes(byte[] serialized) {
            return new String(serialized);
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值