文章目录版权说明: 本文由博主keep丶原创,转载请注明出处。
原文地址: https://blog.csdn.net/qq_38688267/article/details/120787954
- 前言
- 代码
- 服务端
- 客户端
作者有一个项目中考虑到性能和跨平台能力,采用Grpc作为服务间调度的方案,但是Grpc对JAVA的支持太差,使用起来比较麻烦,为了简化部分代码,作者封装了Grpc的全局异常捕获功能。
代码 服务端@GrpcGlobalServerInterceptor
public class GrpcServerInterceptor implements ServerInterceptor {
@Override
public ServerCall.Listener interceptCall(ServerCall serverCall,
metadata metadata,
ServerCallHandler serverCallHandler) {
return new ForwardingServerCallListener.SimpleForwardingServerCallListener(serverCallHandler.startCall(serverCall, metadata)) {
@Override
public void onHalfClose() {
try {
super.onHalfClose();
} catch (Exception e) {
if (!(e instanceof IllegalArgumentException)) {
e.printStackTrace();
}
// 通过元数据传输消息
metadata.put(metadata.Key.of("message-bin", new metadata.BinaryMarshaller() {
@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);
}
super.onHalfClose();
}
};
}
}
客户端
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
@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 {
@Override
public byte[] toBytes(String value) {
return value.getBytes(StandardCharsets.UTF_8);
}
@Override
public String parseBytes(byte[] serialized) {
return new String(serialized);
}
}
}



