HarmonyOS鸿蒙Next中RCP网络请求的拦截器怎么写呢

HarmonyOS鸿蒙Next中RCP网络请求的拦截器怎么写呢 如题,这个拦截器怎么实现呢?

3 回复

可以通过实现 Interceptor 接口并添加到会话配置来实现。

核心代码

import { rcp } from '@kit.RemoteCommunicationKit';

// 请求拦截器示例(修改请求)
export class RequestInterceptor implements rcp.Interceptor {
  async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
    // 请求前逻辑(如修改URL/Headers)
    console.log(`Requesting ${context.request.url.href}`);
    return next.handle(context); // 继续执行请求
  }
}

// 响应拦截器示例(修改响应)
export class ResponseInterceptor implements rcp.Interceptor {
  async intercept(context: rcp.RequestContext, next: rcp.RequestHandler): Promise<rcp.Response> {
    const response = await next.handle(context); // 先执行请求
    // 响应后逻辑(如修改Headers)
    console.log(`Response received: ${response.statusCode}`);
    return response;
  }
}

完整代码

import {
  RequestConfig, 
  RcpResponse, 
  RcpError,
  RequestInterceptor,
  ResponseInterceptor,
  ErrorInterceptor
} from '../types/RcpTypes';

/**
 * 常用拦截器实现
 */

/**
 * 认证拦截器
 * 自动添加Authorization头
 */
export class AuthInterceptor {
  private token: string;
  private type: string;

  constructor(token: string, type?: string) {
    this.token = token;
    this.type = type || 'Bearer';
  }

  /**
   * 更新令牌
   */
  updateToken(token: string): void {
    this.token = token;
  }

  /**
   * 清除令牌
   */
  clearToken(): void {
    this.token = '';
  }

  /**
   * 拦截器函数
   */
  interceptor: RequestInterceptor = (config: RequestConfig): RequestConfig => {
    if (this.token) {
      if (!config.headers) {
        config.headers = {};
      }
      config.headers['Authorization'] = `${this.type} ${this.token}`;
    }
    return config;
  };
}

/**
 * 日志拦截器
 * 记录请求和响应信息
 */
export class LogInterceptor {
  private enableRequest: boolean;
  private enableResponse: boolean;
  private enableError: boolean;

  constructor(
    enableRequest?: boolean,
    enableResponse?: boolean,
    enableError?: boolean
  ) {
    this.enableRequest = enableRequest !== false;
    this.enableResponse = enableResponse !== false;
    this.enableError = enableError !== false;
  }

  /**
   * 请求拦截器
   */
  requestInterceptor: RequestInterceptor = (config: RequestConfig): RequestConfig => {
    if (this.enableRequest) {
      console.info('RCP Request:', {
        method: config.method,
        url: config.url,
        headers: config.headers,
        timestamp: new Date().toISOString()
      });
    }
    return config;
  };

  /**
   * 响应拦截器
   */
  responseInterceptor: ResponseInterceptor = (response: RcpResponse<Object>): RcpResponse<Object> => {
    if (this.enableResponse) {
      console.info(' RCP Response:', {
        status: response.status,
        statusText: response.statusText,
        ok: response.ok,
        dataSize: this.getDataSize(response.data),
        timestamp: new Date().toISOString()
      });
    }
    return response;
  };

  /**
   * 错误拦截器
   */
  errorInterceptor: ErrorInterceptor = (error: RcpError): RcpError => {
    if (this.enableError) {
      console.error(' RCP Error:', {
        code: error.code,
        message: error.message,
        data: error.data,
        timestamp: new Date().toISOString()
      });
    }
    return error;
  };

  /**
   * 获取数据大小描述
   */
  private getDataSize(data: Object): string {
    try {
      if (typeof data === 'string') {
        return `${data.length} chars`;
      }
      if (data instanceof ArrayBuffer) {
        return `${data.byteLength} bytes`;
      }
      return `${JSON.stringify(data).length} chars`;
    } catch {
      return 'unknown size';
    }
  }
}

/**
 * 重试拦截器
 * 自动重试失败的请求
 */
interface GeneratedTypeLiteralInterface_1 {
  retryCount?: number;
}

export class RetryInterceptor {
  private maxRetries: number;
  private retryDelay: number;
  private shouldRetry: (error: RcpError) => boolean;

  constructor(
    maxRetries?: number,
    retryDelay?: number,
    shouldRetry?: (error: RcpError) => boolean
  ) {
    this.maxRetries = maxRetries || 3;
    this.retryDelay = retryDelay || 1000;
    this.shouldRetry = shouldRetry || this.defaultShouldRetry;
  }

  /**
   * 默认重试条件
   */
  private defaultShouldRetry = (error: RcpError): boolean => {
    // 网络错误或5xx服务器错误时重试
    return error.code >= 500 || error.code === 0;
  };

  /**
   * 错误拦截器(用于重试逻辑)
   */
  errorInterceptor: ErrorInterceptor = async (error: RcpError): Promise<RcpError> => {
    const defaultData: Record<string, Object> = {};
    const errorData = (error.data as GeneratedTypeLiteralInterface_1) || defaultData;
    const retryCount = (errorData.retryCount as number) || 0;

    if (this.shouldRetry(error) && retryCount < this.maxRetries) {
      console.info(` Retrying request (${retryCount + 1}/${this.maxRetries})`);
      
      // 延迟重试
      await this.delay(this.retryDelay * Math.pow(2, retryCount));
      
      // 标记重试次数
      const updatedData: Record<string, Object> = {};
      if (error.data) {
        Object.keys(error.data).forEach(key => {
          updatedData[key] = error.data![key];
        });
      }
      updatedData.retryCount = retryCount + 1;
      updatedData.shouldRetry = true;
      error.data = updatedData;
    }

    return error;
  };

  /**
   * 延迟函数
   */
  private delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

/**
 * 超时拦截器
 * 为请求设置统一超时时间
 */
export class TimeoutInterceptor {
  private defaultTimeout: number;

  constructor(timeout?: number) {
    this.defaultTimeout = timeout || 30000;
  }

  /**
   * 请求拦截器
   */
  interceptor: RequestInterceptor = (config: RequestConfig): RequestConfig => {
    if (!config.timeout) {
      config.timeout = this.defaultTimeout;
    }
    return config;
  };
}

更多关于HarmonyOS鸿蒙Next中RCP网络请求的拦截器怎么写呢的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,RPC网络请求拦截器通过@ohos.net.http模块的HttpInterceptor接口实现。你需要创建一个实现该接口的类,并重写onIntercept方法。在该方法中,你可以访问和修改请求(request)与响应(response)对象,例如添加公共请求头或处理通用错误。最后,使用HttpClient.addInterceptor()方法注册该拦截器。

在HarmonyOS Next中,RCP(Remote Communication Proxy)网络请求的拦截器可以通过实现 Interceptor 接口来定义,并在创建RPC调用时通过 CallOptions 进行配置。以下是核心实现步骤:

  1. 定义拦截器类:创建一个类实现 ohos.rpc.Interceptor 接口。该接口主要包含 intercept 方法,您可以在请求发出前和收到响应后插入自定义逻辑。

    import ohos.rpc.*;
    
    public class MyRpcInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws RemoteException {
            // 1. 请求发出前的处理:可修改请求数据、添加头部等
            Request originalRequest = chain.request();
            // 例如,添加一个自定义头部
            // 注意:Request的构建可能需要使用Request.Builder
            // 这里是一个示意,实际API可能有所不同
            // Request newRequest = originalRequest.newBuilder()
            //        .addHeader("Custom-Header", "Value")
            //        .build();
    
            // 2. 将请求传递给下一个拦截器或最终发送
            Response response = chain.proceed(originalRequest);
    
            // 3. 收到响应后的处理:可解析、修改响应数据等
            // 例如,检查状态码或记录日志
            if (response.getCode() != 0) {
                // 处理错误
            }
            return response;
        }
    }
    
  2. 配置并使用拦截器:在构建RPC调用(如通过 RemoteProxyRemoteObject)时,通过 CallOptions 设置拦截器。

    // 创建拦截器实例
    MyRpcInterceptor interceptor = new MyRpcInterceptor();
    
    // 构建CallOptions并添加拦截器
    CallOptions options = new CallOptions.Builder()
            .addInterceptor(interceptor)
            .build();
    
    // 在创建远程调用或发送请求时传入options
    // 例如,使用RemoteProxy进行调用时
    // IRemoteObject remoteObject = ...; // 获取远程对象
    // MyRemoteProxy proxy = RemoteProxy.create(remoteObject, MyRemoteProxy.class, options);
    

关键点说明

  • intercept 方法:这是拦截器的核心。参数 Chain 提供了请求对象和 proceed 方法,用于将请求传递下去。务必调用 chain.proceed() 以确保请求继续执行。
  • 请求与响应对象:注意查阅HarmonyOS Next的官方API文档,确认 RequestResponse 的具体构建与使用方法,因为不同版本可能存在差异。
  • 线程安全:拦截器可能被多个线程调用,确保实现是线程安全的。
  • 性能:避免在拦截器中执行耗时操作,以免影响网络请求效率。

如果您的场景需要多个拦截器,可以创建多个 Interceptor 实例并按顺序添加到 CallOptions 中,它们会按添加顺序依次执行。

以上代码基于HarmonyOS Next的常见RPC模式,具体实现请根据实际使用的RPC框架或API进行调整。

回到顶部