Retrofit官网文档评注

Introduction

Retrofit turns your HTTP API into a Java interface.
它把一个http的请求用一个接口的方式来实现。比较新奇的想法。

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

The Retrofit class generates an implementation of the GitHubService interface.

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);//接口也是有类文件的,估计要用反射来处理一些细节

Each Call from the created GitHubService can make a synchronous or asynchronous HTTP request to the remote webserver.

可以实现同步和异步请求

Call<List<Repo>> repos = service.listRepos("octocat");

这个请求实际上请求的url是
https://api.github.com/users/octocat/repos
Use annotations to describe the HTTP request:
库使用注解来表示http请求。刚刚开始看注解的时候,感觉并没有什么大用处,不过后来发现注解真的很有用,spring各种注解,减少了配置文件的手工配置。这里用注解实现http请求。感觉注解现在也有功能上的承担了。
URL parameter replacement and query parameter support
Object conversion to request body (e.g., JSON, protocol buffers)
Multipart request body and file upload
Note: This site is still in the process of being expanded for the new 2.0 APIs.

API Declaration

Annotations on the interface methods and its parameters indicate how a request will be handled.

REQUEST METHOD

Every method must have an HTTP annotation that provides the request method and relative URL. There are five built-in annotations: GET, POST, PUT, DELETE, and HEAD. The relative URL of the resource is specified in the annotation.

@GET("users/list")

You can also specify query parameters in the URL.

@GET("users/list?sort=desc")

这个就是一个请求。会直接加载baseurl后面。

URL MANIPULATION

A request URL can be updated dynamically using replacement blocks and parameters on the method. A replacement block is an alphanumeric string surrounded by { and }. A corresponding parameter must be annotated with @Path using the same string.
url里面的注解可以用上{}括起来。这样我们可以在方法里面用@path注解然后把传进来的参数直接替换到url相应的位置上。

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

Query parameters can also be added.
还可以增加url里面的请求参数

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);

上面是对应一个的情况group/{id}/users?sort=sort 对应这个url。方法里面sort传递的字符串直接增加到sort=后面。这个应该都懂吧。
For complex query parameter combinations a Map can be used.
可以使用一个map进行传递。一次传一堆参数过去。

@GET(“group/{id}/users”)
Call

REQUEST BODY

An object can be specified for use as an HTTP request body with the @Body annotation.
body应该值对应于post方式的才有。body就相当于你用java 建立以个连接之后,用流传的内容。

@POST("users/new")
Call<User> createUser(@Body User user);

The object will also be converted using a converter specified on the Retrofit instance. If no converter is added, only RequestBody can be used.
body是需要转化的。但是如何进行转化这里面没有说。

FORM ENCODED AND MULTIPART

这里面要补充一些知识,就是什么事form encoded 什么事multiparty。。。这两个都是数据提交的方式,当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2…),然后把这个字串append到url后面,用?分割,加载这个新的url。 当action为post时候,浏览器把form数据封装到http body中,然后发送到server。

application/x-www-form-urlencoded: 窗体数据被编码为名称/值对。这是标准的编码格式。
multipart/form-data: 窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分。这种方式一般用来上传文件
text/plain: 窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。

formencode举例

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3   //这个就是编码后的表单数据

multipart

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 mutipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 –boundary 开始,紧接着内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 –boundary– 标示结束。关于 mutipart/form-data 的详细定义

当然还有一些其他的编码方式比如
application/json

现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。

POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}

text/xml
XML 作为编码方式的远程调用规范。

POST http://www.example.com HTTP/1.1
Content-Type: text/xml
<?xml version="1.0"?>
<methodCall>
    <methodName>examples.getStateName</methodName>
    <params>
        <param>
            <value><i4>41</i4></value>
        </param>
    </params>
</methodCall>

Methods can also be declared to send form-encoded and multipart data.

Form-encoded data is sent when @FormUrlEncoded is present on the method. Each key-value pair is annotated with @Field containing the name and the object providing the value.

@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);

Multipart requests are used when @Multipart is present on the method. Parts are declared using the @Part annotation.

@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

Multipart parts use one of Retrofit’s converters or they can implement RequestBody to handle their own serialization.
multipart也是需要转换的。

HEADER MANIPULATION

You can set static headers for a method using the @Headers annotation.
静态设置头部

@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
@Headers({
    "Accept: application/vnd.github.v3.full+json",
    "User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);

Note that headers do not overwrite each other. All headers with the same name will be included in the request.
头部并不会相互覆盖,所有相同的名字头部都会在请求中包括。
A request Header can be updated dynamically using the @Header annotation. A corresponding parameter must be provided to the @Header. If the value is null, the header will be omitted. Otherwise, toString will be called on the value, and the result used.
可以动态的添加头部信息。如果提供参数是null,那么头部不会包括这个信息。并且提供的参数的toString会被调用

@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

Headers that need to be added to every request can be specified using an OkHttp interceptor.
可以用okhttp的拦截器对每次请求进行头部添加,但是okhttp并不会。

SYNCHRONOUS VS. ASYNCHRONOUS

Call instances can be executed either synchronously or asynchronously. Each instance can only be used once, but calling clone() will create a new instance that can be used.
每个call实例只能用一次。不过可以用克隆方法,复制一个实例在调用。

On Android, callbacks will be executed on the main thread. On the JVM, callbacks will happen on the same thread that executed the HTTP request.
在安卓上返回是在主线程执行的。在jvm上,在执行请求的线程执行。所以这么说,用retrofit的所有返回都会返回到主线程上,我们要处理一下,毕竟安卓主线程如果操作过多会造成程序未响应异常。。这也是为啥RxJava和retrofit进行整合的原因吧。Rxjava进行线程切换巨方便无比。

Retrofit Configuration

Retrofit is the class through which your API interfaces are turned into callable objects. By default, Retrofit will give you sane defaults for your platform but it allows for customization.

CONVERTERS

By default, Retrofit can only deserialize HTTP bodies into OkHttp’s ResponseBody type and it can only accept its RequestBody type for @Body.
默认的retrofit只能反序列化OKhttp支持的返回类型。但是可以引入其他的库进行增强下面就有。我看到了xml和json。
Converters can be added to support other types. Six sibling modules adapt popular serialization libraries for your convenience.

Gson: com.squareup.retrofit2:converter-gson
Jackson: com.squareup.retrofit2:converter-jackson
Moshi: com.squareup.retrofit2:converter-moshi
Protobuf: com.squareup.retrofit2:converter-protobuf
Wire: com.squareup.retrofit2:converter-wire
Simple XML: com.squareup.retrofit2:converter-simplexml
Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
Here’s an example of using the GsonConverterFactory class to generate an implementation of the GitHubService interface which uses Gson for its deserialization.

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com")
    .addConverterFactory(GsonConverterFactory.create())//添加转换工厂。
    .build();

GitHubService service = retrofit.create(GitHubService.class);

CUSTOM CONVERTERS

可以自定义转换器。
If you need to communicate with an API that uses a content-format that Retrofit does not support out of the box (e.g. YAML, txt, custom format) or you wish to use a different library to implement an existing format, you can easily create your own converter. Create a class that extends the Converter.Factory class and pass in an instance when building your adapter.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值