retrofit 初探

引用

maven
<dependency>
  <groupId>com.squareup.retrofit2</groupId>
  <artifactId>retrofit</artifactId>
  <version>2.1.0</version>
</dependency>
gradle
    api 'com.squareup.retrofit2:retrofit:2.1.0'
github

github website

个人意见

其实,最适合使用 retrofit 的是 rest 请求类的交互,如果具体的请求参数是以 url 区分业务逻辑,请求参数通过 json 进行的,那其实 retrofit 不太适用

俗话说,demo 是最好的学习 先来看看怎么定义业务逻辑

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

这里的{user}是一个会在实际使用时会被动态改变的,会根据 String user 中的变量而改变

public class RetrofitDemo {
  private static OkHttpClient client;

    static {
        client = new OkHttpClient.Builder()
                .addInterceptor(new HttpInterceptor())
                .build();
    }

    public static void main(String[] args) throws IOException {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://127.0.0.1:32001")
                .addConverterFactory(GsonConverterFactory.create())
  //              .addConverterFactory(StringConverterFactory.create())
                .client(client)
                .build();

        RequestServer requestServer = retrofit.create(RequestServer.class);
        TestEntity bean = new TestEntity();
        bean.setTest("text1");
        Call<ResponseEntity> call = requestServer.post("ping", "test", bean);
        Response<ResponseEntity> response = call.execute();
        ResponseEntity body = response.body();
        System.out.println(body.toString());
    }
}

在上述的代码中 访问的 url 是 http://127.0.0.1:32001/ping/test 请求的方式是post 返回值是Call<ResponseEntity> 这里的具体访问是框架实现的 框架会将请求的 Bean 转换成 Json Post 请求到指定的 url

然后返回值也会被转化成对应的类型 这里依赖的是ConverterFactory 这里的使用的GsonConverterFactory 是官方 Demo 中的一个converter

用于实现 bean 到 json 的转化,再将回包转化成 bean 返回

看下GsonConverterFactory的实现

GsonCoveter 这里其实就 4 个关键方法

  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonResponseBodyConverter<>(gson, adapter);
  }

  @Override
  public Converter<?, RequestBody> requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonRequestBodyConverter<>(gson, adapter);
  }
@Override public RequestBody convert(T value) throws IOException {
    Buffer buffer = new Buffer();
    Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
    JsonWriter jsonWriter = gson.newJsonWriter(writer);
    adapter.write(jsonWriter, value);
    jsonWriter.close();
    return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
  }
  @Override public T convert(ResponseBody value) throws IOException {
  JsonReader jsonReader = gson.newJsonReader(value.charStream());
    try {
      return adapter.read(jsonReader);
    } finally {
      value.close();
    }
  }

前两个方法用于生成 Converter

后面的是 Converter 中的方法 用于将 bean 转化成 RequestBody 和将 ResponseBody 转化成 bean

仿照这个自己写一个 Factory StringConverterFactory

public final class StringConverterFactory extends Converter.Factory {

  public static StringConverterFactory create() {
    return new StringConverterFactory();
  }

  private StringConverterFactory() {
  }

  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
    return new StringResponseBodyConverter();
  }

  @Override
  public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    return new StringRequestBodyConverter();
  }
}

StringRequestBodyConverter

final class StringRequestBodyConverter implements Converter<String, RequestBody> {

    StringRequestBodyConverter() {
    }

    @Override
    public RequestBody convert(String s) throws IOException {
        return RequestBody.create(MediaType.parse("text/json"), s);
    }
}

StringResponseBodyConverter

final class StringResponseBodyConverter implements Converter<ResponseBody, String> {

    StringResponseBodyConverter() {
    }

    @Override
    public String convert(ResponseBody value) throws IOException {

        try {
            return value.string();
        } finally {
            value.close();
        }
    }
}

其实就是 Factory 中的两个方法控制使用哪个转化器转化 两个 Convert 控制怎么转化