我有一个使用springgrpc的项目。我创建了一个拦截器,当服务成功响应时,拦截器工作正常,但当服务捕获异常时,拦截器不工作。
服务:
@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方法。
是否有任何方法可以拦截异常,并在拦截器中获取de-request body?
谢谢!
1条答案
按热度按时间9o685dep1#
如果
myService.doStuff()
抛出异常,没有发送任何消息。sendMessage()
不会打电话的,但是close(Status, Metadata)
还是会的。的当前用法
headers
它坏了。Metadata
不是线程安全的,并且您不知道对象的当前“所有者”正在使用它做什么。headers.get(REQUEST_ID_METADATA_KEY)
应在interceptCall()
直接,在回来之前。现在还不完全清楚
onMessage()
是的,但看起来你应该复制一份元数据(new Metadata().merge(headers
)内interceptCall()
.