我有由protobuf定义的服务(gRPC),该服务具有一种调用方法。 我想使用gRPC服务的clientStub调用该方法并传递标头(通常与其他方法一起使用),但是我找不到在gRPC中通常如何做。我决定通过 ClientInterceptor 进行操作,并将ClientInterceptor放入ClientStub。
public class ClientHeadersInterceptor implements ClientInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(ClientHeadersInterceptor.class);
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
@Override
public void start(Listener<RespT> responseListener, Metadata headers) {
headers.put("test", "test");
headers.put("test1", "test");
super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) {
@Override
public void onHeaders(Metadata headers) {
LOGGER.info("header received from server:" + headers);
}
}, headers);
}
};
}
}
所以我在业务逻辑中需要标头的这些值。我的意思是如何在gRPC的 impl 服务中获取这些值?
我通过创建 ServerInterceptor 来解决此问题,该服务器获取元数据的所有值并将其放在Context中。
@GRpcGlobalInterceptor
public class ServeInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall,
Metadata metadata,
ServerCallHandler<ReqT, RespT> serverCallHandler) {
Context current = Context.current();
current = Context.current()
.withValue("test", metadata.get("test"))
.withValue("test1", metadata.get("test1"));
return Contexts.interceptCall(current, serverCall, metadata, serverCallHandler);
}
}
然后,最后,当我将所有内容都放在Context中时,我会在需要获取这些值的任何地方使用上下文。
String testValue = Context.key("test").get();
String test1Value = Context.key("test1").get();
那么,这真的是从客户端获取服务元数据(标头)的唯一方法吗?