Java Spring gRPC-如何使用正文信息截获异常

Java Spring gRPC-如何使用正文信息截获异常,java,spring,grpc,grpc-java,Java,Spring,Grpc,Grpc Java,我有一个使用spring gRPC的项目。我创建了一个拦截器,当服务响应成功时,拦截器工作正常,但当服务捕获异常时,拦截器不工作 服务: @GrpcService public class ClientAppImpl extends ClientAppGrpc.ClientAppImplBase { @Autowired MyService myService; @Override public void myMethod(Request request, S

我有一个使用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());
        }

    }
}
@GrpcService
公共类ClientAppImpl扩展了ClientAppGrpc.ClientAppImplBase{
@自动连线MyService MyService;
@凌驾
公共void myMethod(请求请求、StreamObserver响应Observer){
试一试{
Response-Response=myService.doStuff(请求);
responseObserver.onNext(响应);
responseObserver.onCompleted();
}捕获(例外情况除外){
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);
            }
        };
    }
}
@GrpcGlobalServerInterceptor
公共类GrpcServerInterceptor实现ServerInterceptor{
公共静态最终字符串请求\u ID\u HEADER=“请求ID bin”;
公共静态最终元数据.Key REQUEST\u ID\u Metadata\u Key=Metadata.Key.of(REQUEST\u ID\u HEADER,Metadata.BINARY\u BYTE\u MARSHALLER);
私有静态最终映射调用=new HashMap();
@凌驾
public ServerCall.Listener interceptCall(ServerCall调用、元数据头、ServerCallHandler-next){
ForwardingServerCall responseServerCall=新建ForwardingServerCall.SimpleForwardingServerCall(调用){
@凌驾
公共无效发送消息(响应响应){
String callId=新字符串(headers.get(REQUEST_ID_METADATA_KEY));
GrpcCall GrpcCall=CALLS.get(callId);
grpcCall.setResponse(响应);
GrpcCallProcessor GrpcCallProcessor=新的GrpcCallProcessor(grpcCall);
grpcCallProcessor.processCall();
super.sendMessage(响应);
}
};
ServerCall.Listener listenerWithContext=Context.interceptCall(Context.current(),responseServerCall,headers,next);
返回新的ForwardingServerCallListener.SimpleForwardingServerCallListener(listenerWithContext){
@凌驾
公共消息无效(请求请求){
字符串callId=UUID.randomUUID().toString();
headers.put(请求\u ID\u元数据\u键,callId.getBytes());
GrpcCall GrpcCall=新GrpcCall();
grpcCall.setCall(调用);
grpcCall.setHeaders(标题);
grpcCall.setRequest(请求);
CALLS.put(callId、grpcCall);
super.onMessage(请求);
}
};
}
}
当服务未捕获异常时,拦截器工作正常,并调用sendMessage方法。但是,当服务捕获异常时,不会调用sendMessage方法

是否有任何方法可以拦截异常,并在拦截器中获取de请求正文

谢谢

如果
myService.doStuff()
抛出异常,则不会发送任何消息
sendMessage()
不会被调用,但是
close(状态、元数据)
仍然会被调用

标题的当前用法已中断<代码>元数据
不是线程安全的,您不知道对象的当前“所有者”正在使用它做什么
headers.get(REQUEST\u ID\u METADATA\u KEY)
应该在
interceptCall()中直接执行,然后返回

尚不完全清楚
onMessage()
的用途,但看起来您应该在
interceptCall()中复制元数据(
new metadata().merge(headers