gRPC 拦截器是一种强大的功能,用于在 gRPC 调用过程中对请求和响应进行拦截、修改和监视。拦截器允许你在请求和响应被发送和接收之前或之后插入自定义逻辑,从而实现各种功能,如认证、授权、日志记录、错误处理等。拦截器可以在客户端和服务器两端使用,它们是实现横切关注点的一种重要方式。
gRPC拦截器分为两种,即客户端拦截器和服务端拦截器,我们现在通过这两种拦截器来实现日志记录
public class ServerLoggingInterceptor implements ServerInterceptor {
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
System.out.println("Received request: " + call.getMethodDescriptor().getFullMethodName());
ServerCall.Listener<ReqT> listener = next.startCall(call, headers);
return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(listener) {
@Override
public void onMessage(ReqT message) {
System.out.println("Received message: " + message.toString());
super.onMessage(message);
}
@Override
public void onHalfClose() {
System.out.println("Client closed the call.");
super.onHalfClose();
}
@Override
public void onCancel() {
System.out.println("Call cancelled by client.");
super.onCancel();
}
@Override
public void onComplete() {
System.out.println("Call completed.");
super.onComplete();
}
};
}
配置服务端拦截器
public class HelloServer {
public static void main(String[] args) throws Exception {
Server server = ServerBuilder.forPort(9090)
.addService(new HelloServiceIpl())
.intercept(new ServerLoggingInterceptor())
.build();
server.start();
System.out.println("gRPC服务启动");
server.awaitTermination();
}
}
public class ClientLoggingInterceptor implements ClientInterceptor {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
CallOptions callOptions, Channel next) {
System.out.println("Sending request: " + method.getFullMethodName());
// 创建一个客户端调用,传递给下一个拦截器或通道
return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(
next.newCall(method, callOptions)) {
@Override
public void start(Listener<RespT> responseListener, Metadata headers) {
// 在调用开始前执行操作
super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) {
@Override
public void onMessage(RespT message) {
// 处理接收到的响应消息
System.out.println("Received response: " + message.toString());
super.onMessage(message);
}
}, headers);
}
};
}
}
配置客户端拦截器
ManagedChannel channel = ManagedChannelBuilder
.forAddress("localhost", 9090)
.usePlaintext()
.intercept(new ClientLoggingInterceptor())
.build();