【发布时间】:2021-01-15 20:11:23
【问题描述】:
我有一个使用 spring gRPC 的项目。我创建了一个拦截器,当服务响应成功时,拦截器工作正常,但是当服务捕获异常时,拦截器不起作用。
服务:
@GrpcService
public class ClientAppImpl extends ClientAppGrpc.ClientAppImplBase {
@Autowired MyService myService;
@Override
public void myMethod(Request request, StreamObserver<CreateDigitalCertificateResponse> responseObserver) {
try {
Response response = myService.doStuff(request);
responseObserver.onNext(response);
responseObserver.onCompleted();
} catch(Exception ex) {
responseObserver.onError(Status.INTERNAL.withDescription(exception.getMessage()).withCause(exception).asRuntimeException());
}
}
}
拦截器:
@GrpcGlobalServerInterceptor
public class GrpcServerInterceptor implements ServerInterceptor {
public static final String REQUEST_ID_HEADER = "request-id-bin";
public static final Metadata.Key<byte[]> REQUEST_ID_METADATA_KEY = Metadata.Key.of(REQUEST_ID_HEADER, Metadata.BINARY_BYTE_MARSHALLER);
private static final Map<String, GrpcCall> CALLS = new HashMap<>();
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
ForwardingServerCall<ReqT, RespT> responseServerCall = new ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) {
@Override
public void sendMessage(RespT response) {
String callId = new String(headers.get(REQUEST_ID_METADATA_KEY));
GrpcCall grpcCall = CALLS.get(callId);
grpcCall.setResponse(response);
GrpcCallProcessor grpcCallProcessor = new GrpcCallProcessor(grpcCall);
grpcCallProcessor.processCall();
super.sendMessage(response);
}
};
ServerCall.Listener<ReqT> listenerWithContext = Contexts.interceptCall(Context.current(), responseServerCall, headers, next);
return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(listenerWithContext) {
@Override
public void onMessage(ReqT request) {
String callId = UUID.randomUUID().toString();
headers.put(REQUEST_ID_METADATA_KEY, callId.getBytes());
GrpcCall grpcCall = new GrpcCall();
grpcCall.setCall(call);
grpcCall.setHeaders(headers);
grpcCall.setRequest(request);
CALLS.put(callId, grpcCall);
super.onMessage(request);
}
};
}
}
当服务没有捕获到异常时,拦截器正常工作,并调用方法 sendMessage。但是当服务捕获异常时,不会调用 sendMessage 方法。
有什么方法可以拦截异常,并在拦截器中获取请求体?
谢谢!
【问题讨论】:
标签: java spring grpc grpc-java