0

我正在使用 json-annotation 为不同的响应集创建不同的 .g.dart 类。现在,当我使用 Chopper Client 发出请求并将响应映射到模型类时,我正在创建转换器。但我只能为斩波器客户端分配一个转换器。我想要实现的是使用 get_it 包来初始化 chopper 客户端。如何在发出不同请求时为斩波器客户端分配不同的转换器。 这是 get_it 包用于初始化类的基类。

base.dart

import 'package:chopper/chopper.dart' as chopper;

chopper.ChopperClient getBaseChopperClient(GetIt c) {
  return chopper.ChopperClient(
    baseUrl: 'https://',
    interceptors: [chopper.HttpLoggingInterceptor()],
    converter: HomeModelConverter(),
    errorConverter: chopper.JsonConverter(),
  );
}

c.registerLazySingleton(() {
  var chopper = getBaseChopperClient(c);
  return chopper;
});

c.registerFactory(() => HomeApiService.create(c<chopper.ChopperClient>()));

我正在使用 HomeModelConverter 发出 Get 请求并将响应映射到 HomeModelResponse 的这个 ChopperService 类,并且这个 HomeModelConverter 在上面的 chopper 客户端对象中分配。

home_api_service.dart

part 'home_api.chopper.dart';

@ChopperApi(baseUrl: '')
abstract class HomeApiService extends ChopperService {
  @Get(path: '')
  Future<Response<HomeModelResponse>> getData();

  static HomeApiService create([ChopperClient? client]) =>
      _$HomeApiService(client);
}

这是特定于 HomeModelResponse 的转换器类。在 decodeJson 函数中,我们明确提到它来解码到 HomeModelResponse。

home_model_converter.dart

class HomeModelConverter implements Converter {
  @override
  Request convertRequest(Request request) {
    final req = applyHeader(
      request,
      contentTypeKey,
      jsonHeaders,
      override: false,
    );

    return encodeJson(req);
  }

  Request encodeJson(Request request) {
    var contentType = request.headers[contentTypeKey];
    if (contentType != null && contentType.contains(jsonHeaders)) {
      return request.copyWith(body: json.encode(request.body));
    }
    return request;
  }

  Response<BodyType> decodeJson<BodyType, InnerType>(Response response) {
    var contentType = response.headers[contentTypeKey];
    var body = response.body;
    if (contentType != null && contentType.contains(jsonHeaders)) {
      body = utf8.decode(response.bodyBytes);
    }
    try {
      var mapData = json.decode(body);
      var popular = HomeModelResponse.fromJson(mapData);
      return response.copyWith<BodyType>(body: popular as BodyType);
    } catch (e) {
      chopperLogger.warning(e);
      return response.copyWith<BodyType>(body: body);
    }
  }

  @override
  Response<BodyType> convertResponse<BodyType, InnerType>(Response response) {
    return decodeJson<BodyType, InnerType>(response);
  }
}

这是 HomeModelResponse,传入的响应将自动映射到其中。

home_model_response.dart

part 'home_model_response.g.dart';

@JsonSerializable()
class HomeModelResponse {
  ------------
-----------
  HomeModelResponse({
    ---------
    ---------
  });
  factory HomeModelResponse.fromJson(Map<String, dynamic> json) =>
      _$HomeModelResponseFromJson(json);
  Map<String, dynamic> toJson() => _$HomeModelResponseToJson(this);
}

上面的代码对 home_api_service 工作正常,我得到了正确的响应。 现在我想创建另一个服务,例如 AddApiService。这将有不同的转换器。如何在斩波器客户端中动态更改转换器。现在 HomeModelConverter 在初始化时是硬编码分配的。我不想为每个转换器创建多个 ChopperClient。卡在这里。或任何创建通用转换器的选项

如果有人可以建议这种方法是否可行,或者是否有更好的方法可以遵循。

4

1 回答 1

0

尝试了自己并做了一些解决方法。现在按照我的要求工作。

修改 HomeApiService 的初始化如下:

c.registerFactory(() => HomeModelConverter());

c.registerFactory(() => HomeApiService.create(
    getBaseChopperClient(c, c<HomeModelConverter>())));

修改了斩波器客户端的初始化如下。这里唯一的缺点是,对于每个新的 Chopper 服务,都会创建新的 Chopper 客户端对象。

chopper.ChopperClient getBaseChopperClient(
  GetIt c, chopper.Converter converter) {
return chopper.ChopperClient(
  baseUrl: '', // provide your own base url
  interceptors: [chopper.HttpLoggingInterceptor()],
  converter: converter,
  errorConverter: chopper.JsonConverter(),
);

}

于 2021-04-11T05:46:22.100 回答