用于Android和Java平台的一款类型安全的HTTP客户端,通过一个Java接口实现HTTP请求对象,如下:
public interface Github {
@GET("/repos/{owner}/{repo}/contributors")
Call> contributors(
@Path("owner") String owner,
@Path("repo") String repo);
}
//retrofit2 依赖库
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
//Gson 数据解析器依赖库
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
//okhttp3 输出网络请求日志依赖库
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
//创建接收服务器返回数据的类
public class Contributor {
public final String login;
public final int contributions;
public Contributor(String login, int contributions) {
this.login = login;
this.contributions = contributions;
}
}
//创建用于网络请求的接口
public interface Github {
@GET("/repos/{owner}/{repo}/contributors")
Call> contributors(
@Path("owner") String owner,
@Path("repo") String repo);
}
HttpLoggingInterceptor loggingInterceptor;
//打印网络请求相关日志
loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
//打印retrofit日志
Log.i("retrofitLog: ", message);
}
});
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//为了打印日志,需要配置OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_GITHUB_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
//创建网络接口实例
Github github = retrofit.create(Github.class);
//对发送请求进行封装
Call> call = github.contributors("square", "retrofit");
//发送同步请求时不能直接在UI线程进行,不然会报错:NetworkOnMainThreadException
//发送请求,获取请求的数据
List contributors = call.execute().body();
StringBuilder result = new StringBuilder();
for (Contributor contributor : contributors) {
result.append(contributor.login + " (" + contributor.contributions + ")\n");
}
Log.e("result", result.toString());
MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView tv_request_result;
public static final String API_GITHUB_URL = "https://api.github.com";
HttpLoggingInterceptor loggingInterceptor;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle data = msg.getData();
String result = data.getString("result");
tv_request_result.setText(result);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//打印网络请求相关日志
loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
//打印retrofit日志
Log.i("retrofitLog: ", message);
}
});
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
new Thread(runnable).start(); //不能在UI线程中进行网络请求
}
private void initView() {
tv_request_result = (TextView) findViewById(R.id.tv_request_result);
}
//发送网络请求
private String request() throws IOException {
//为了打印日志,需要配置okhttp
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build();
//创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_GITHUB_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
//创建网络接口实例
Github github = retrofit.create(Github.class);
//对发送请求进行封装
Call> call = github.contributors("square", "retrofit");
//发送请求,获取请求的数据
List contributors = call.execute().body();
StringBuilder result = new StringBuilder();
for (Contributor contributor : contributors) {
result.append(contributor.login + " (" + contributor.contributions + ")\n");
}
Log.e("result", result.toString());
return result.toString();
}
//网络请求线程
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
String result = request();
Message msg = new Message();
Bundle data = new Bundle();
data.putString("result", result);
msg.setData(data);
handler.sendMessage(msg);
} catch (IOException e) {
Log.e("request_erro", e.toString());
}
}
};
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_request_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp" />
ScrollView>
LinearLayout>
07-02 16:07:41.145 17443-17462/com.example.xuyue.learnretrofit I/retrofitLog:: --> GET https://api.github.com/repos/square/retrofit/contributors http/1.1
--> END GET
07-02 16:07:43.275 17443-17462/com.example.xuyue.learnretrofit I/retrofitLog:: <-- 200 OK https://api.github.com/repos/square/retrofit/contributors (2129ms)
Server: GitHub.com
Date: Mon, 02 Jul 2018 08:07:45 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Status: 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 30
X-RateLimit-Reset: 1530522209
Cache-Control: public, max-age=60, s-maxage=60
07-02 16:07:43.276 17443-17462/com.example.xuyue.learnretrofit I/retrofitLog:: Vary: Accept
ETag: W/"0313af265d6c3206fe7e38545918e2bf"
Last-Modified: Mon, 02 Jul 2018 07:42:01 GMT
X-GitHub-Media-Type: github.v3; format=json
Link: //api.github.com/repositories/892275/contributors?page=2>; rel="next", ; rel="last"
Access-Control-Expose-Headers: ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
Access-Control-Allow-Origin: *
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Frame-Options: deny
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
Content-Security-Policy: default-src 'none'
X-Runtime-rack: 0.075905
X-GitHub-Request-Id: 90E0:3CD2:61BDD85:BCDE66D:5B39DD50
07-02 16:07:43.288 17443-17462/com.example.xuyue.learnretrofit I/retrofitLog:: [{"login":"JakeWharton","id":66577,"node_id":"MDQ6VXNlcjY2NTc3","avatar_url":"https://avatars0.githubusercontent.com/u/66577?v=4","gravatar_id":"","url":"https://api.github.com/users/JakeWharton","html_url":"https://github.com/JakeWharton","followers_url":"https://api.github.com/users/JakeWharton/followers","following_url":"https://api.github.com/users/JakeWharton/following{/other_user}","gists_url":"https://api.github.com/users/JakeWharton/gists{/gist_id}","starred_url":"https://api.github.com/users/JakeWharton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JakeWharton/subscriptions","organizations_url":"https://api.github.com/users/JakeWharton/orgs","repos_url":"https://api.github.com/users/JakeWharton/repos","events_url":"https://api.github.com/users/JakeWharton/events{/privacy}","received_events_url":"https://api.github.com/users/JakeWharton/received_events","type":"User","site_admin":false,"contributions":911},{"login":"swankjesse","id":133019,"node_id":"MDQ6VXNlcjEzMzAxOQ==","avatar_url":"https://avatars3.githubusercontent.com/u/133019?v=4","gravatar_id":"","url":"https://api.github.com/users/swankjesse","html_url":"https://github.com/swankjesse","followers_url":"https://api.github.com/users/swankjesse/followers","following_url":"https://api.github.com/users/swankjesse/following{/other_user}","gists_url":"https://api.github.com/users/swankjesse/gists{/gist_id}","starred_url":"https://api.github.com/users/swankjesse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swankjesse/subscriptions","organizations_url":"https://api.github.com/users/swankjesse/orgs","repos_url":"https://api.github.com/users/swankjesse/repos","events_url":"https://api.github.com/users/swankjesse/events{/privacy}","received_events_url":"https://api.github.com/users/swankjesse/received_events","type":"User","site_admin":false,"contributions":224},{"login":"pforhan","id":331925,"node_id":"MDQ6VXNlcjMzMTkyNQ==","avatar_url":"https://avatars3.githubusercontent.com/u/331925?v=4","gravatar_id":"","url":"https://api.github.com/users/pforhan","html_url":"https://github.com/pforhan","followers_url":"https://api.github.com/users/pforhan/followers","following_url":"https://api.github.com/users/pforhan/following{/other_user}","gists_url":"https://api.github.com/users/pforhan/gists{/gist_id}","starred_url":"https://api.github.com/users/pforhan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pforhan/subscriptions","organizations_url":"https://api.github.com/users/pforhan/orgs","repos_url":"https://api.github.com/users/pforhan/repos","events_url":"https://api.github.com/users/pforhan/events{/privacy}","received_events_url":"https://api.github.com/users/pforhan/received_events","type":"User","site_admin":false,"contributions":48},{"login":"eburke","id":63761,"node_id":"MDQ6VXNlcjYzNzYx","avatar_url":"https://avatars0.githubusercontent.com/u/63761?v=4","gravatar_id":"","url":"https://api.github.com/users/eburke","html_url":"https://github.com/eburke","followers_url":"https://api.github.com/users/eburke/followers","following_url":"https://api.github.com/users/eburke/following{/other_user}","gists_url":"https://api.github.com/users/eburke/gists{/gist_id}","starred_url":"https://api.github.com/users/eburke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eburke/subscriptions","organizations_url":"https://api.github.com/users/eburke/orgs","repos_url":"https://api.github.com/users/eburke/repos","events_url":"https://api.github.com/users/eburke/events{/privacy}","received_events_url":"https://api.github.com/users/eburke/received_events","type":"User","site_admin":false,"contributions":36},{"login":"dnkoutso","id":310370,"node_id":"MDQ6VXNlcjMxMDM3MA==","avatar_url":"https://avatars2.githubusercontent.com/u/310370?v=4","gravatar_id":"","url":"https://api.github.com/users/dnkoutso","html_url":"https://github.com/dnkoutso","followers_url":"https://api.github.com/users/dnkoutso/followers","following_url":"https://api.github.com/users/d
<-- END HTTP (28135-byte body)
{
"login": "JakeWharton",
"id": 66577,
"node_id": "MDQ6VXNlcjY2NTc3",
"avatar_url": "https://avatars0.githubusercontent.com/u/66577?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/JakeWharton",
"html_url": "https://github.com/JakeWharton",
"followers_url": "https://api.github.com/users/JakeWharton/followers",
"following_url": "https://api.github.com/users/JakeWharton/following{/other_user}",
"gists_url": "https://api.github.com/users/JakeWharton/gists{/gist_id}",
"starred_url": "https://api.github.com/users/JakeWharton/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/JakeWharton/subscriptions",
"organizations_url": "https://api.github.com/users/JakeWharton/orgs",
"repos_url": "https://api.github.com/users/JakeWharton/repos",
"events_url": "https://api.github.com/users/JakeWharton/events{/privacy}",
"received_events_url": "https://api.github.com/users/JakeWharton/received_events",
"type": "User",
"site_admin": false,
"contributions": 911
}