如何在ServerInterceptor中获取响应类型的Builder?
问题:在gRPC ServerInterceptor中获取响应类型的Builder
我正在编写一个ServerInterceptor,需要返回预定义的响应,但不知道如何获取RespT类型的Builder。方法声明如下:
@Override public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall( ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) { // how to get a builder of RespT here? ... }
我已经通过call.getMethodDescriptor().getResponseMarshaller()获取到响应Marshaller,转换为ReflectableMarshaller<RespT>后能拿到响应的Class,但不知道怎么进一步获取它的Builder。
解决方案
gRPC生成的Protobuf消息类都自带静态的newBuilder()方法,因此可以通过反射调用该方法来获取Builder实例,具体步骤如下:
- 从
MethodDescriptor中获取响应Marshaller,转换为ReflectableMarshaller后拿到响应消息的Class - 反射调用该Class的
newBuilder()静态方法 - 将返回实例转换为对应类型的Builder
代码示例
@Override public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall( ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) { // 获取响应消息的Class MethodDescriptor<ReqT, RespT> methodDescriptor = call.getMethodDescriptor(); ReflectableMarshaller<RespT> responseMarshaller = (ReflectableMarshaller<RespT>) methodDescriptor.getResponseMarshaller(); Class<RespT> responseClass = responseMarshaller.getMessageClass(); // 通过反射创建Builder实例 RespT.Builder responseBuilder = null; try { Method newBuilderMethod = responseClass.getMethod("newBuilder"); responseBuilder = (RespT.Builder) newBuilderMethod.invoke(null); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { // 将反射异常转换为gRPC内部异常返回给客户端 throw Status.INTERNAL.withDescription("无法创建响应Builder").withCause(e).asRuntimeException(); } // 使用Builder构造预定义响应 RespT predefinedResponse = (RespT) responseBuilder.build(); // 后续逻辑:比如直接返回该响应,或者继续处理 ... }
注意事项
- 仅适用于gRPC自动生成的Protobuf消息类,这类类都会自动生成
newBuilder()静态方法 - 反射操作必须处理异常,建议转换为gRPC标准的
Status异常,保证客户端能收到合理的错误反馈 - 如果使用自定义的Marshaller,需要确保对应的消息类也提供了可通过反射调用的Builder创建方法,否则需要调整反射逻辑适配自定义实现
内容的提问来源于stack exchange,提问作者Slava Semushin
相关产品推荐
相关产品推荐

