مشخصات مقاله
-
2717
-
0.0
-
7190
-
0
-
0
استفاده از Retrofit برای ساخت سرویس های بر پایه REST
آموزش Retrofit
Retrofit عبارت است از یک REST Client برای Java و Android که توسط Square ارائه می شود. این کتابخانه، بازیابی و بارگذاری JSON یا هر داده ی ساخت یافته ی دیگری را از طریق یک وب سرویس مبتنی بر REST انجام می دهد. Retrofit را می توان با یک converter تنیظم نموده و برای serialize داده ها مورد استفاده قرار داد. معمولا برای داده هایی که در فرمت JSON ذخیره شده اند از Gson استفاده می شود، با این حال شما می توانید converter های اختصاصی و دلخواه خود را جهت پردازش XML یا دیگر پروتکل ها مورد استفاده قرار دهید. Retrofit از کتابخانه ی OkHttp برای مدیریت درخواست های HTTP بهره می گیرد.
Retrofit به شما این امکان را می دهد از Converter های زیر استفاده نمایید.
- Gson: com.squareup.retrofit:converter-gson
- Jackson: com.squareup.retrofit:converter-jackson
- Moshi: com.squareup.retrofit:converter-moshi
- Protobuf: com.squareup.retrofit:converter-protobuf
- Wire: com.squareup.retrofit:converter-wire
- Simple XML: com.squareup.retrofit:converter-simplexml
برای کار با Retrofit به سه کلاس زیر احتایج دارید.
- کلاس model ویژه ی نگاشت داده های JSON.
- Interface هایی که عملیات و توابع HTTP را تعریف می کنند.
- کلاس Retrofit.Builder – نمونه ای که از این interface استفاده می کند. Builder API امکان تعریف آدرس URL (آدرس سرویس) endpoint را برای عملیات HTTP فراهم می آورد.
می توانید با مراجعه به سایت زیر، داده های مبتنی بر JSON خود را به فرمت POJO (آبجکت های ساده و بدون متد جاوا) تبدیل نمایید.
تمرین: استفاده از Retrofit برای کوئری گرفتن و پرس و جو از Stackoverflow در اندرویدهدف از این تمرین
StackOverflow یک سایت پر بازدید است که برنامه نویس ها مشکلات برنامه نویسی خود را در آن مطرح می کنند. این سایت یک REST API ارائه می کند که به خوبی مستندسازی شده و با توضیحات لازم در اختیار توسعه دهندگان قرار می گیرد. Query ها را می توان با استفاده از این API ساخت. می توانید جهت مشاهده ی مستندات این API و استفاده از قابلیت های آن به آدرس https://api.stackexchange.com/docs/search مراجعه نمایید. در تمرین زیر با کتابخانه ی Retrofit REST و بر اساس تگ هایی که مشخص می شود، می توانید از سوال های پاسخ داده یا تایید نهایی نشده کوئری بگیرید.
در مثال جاری URL کوئری زیر را بکار می بریم. تگ ها از طریق کد ما مشخص می شوند.
https://api.stackexchange.com/2.2/search?order=desc&sort=activity&tagged=android&site=stackoverflow
آموزش ساخت پروژه و تنظیمات اولیه
یک اپلیکیشن اندروید به نام com.vogella.android.retrofitstackoverflow ایجاد نمایید. این اپلیکیشن بایستی اسم com.vogella.android.retrofitstackoverflow را به عنوان top level package مورد استفاده قرار دهد.
کتابخانه ی زیر را به فایل build.gradle اضافه نمایید.
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
مجوز لازم برای دسترسی به اینترنت را در فایل تنظیمات (manifest) اپلیکیشن تنظیم نمایید.
آموزش API و کلاس adapter Retrofit
در پاسخ JSON ای که از StackOverflow دریافت می شود، تنها به title و link نیاز داریم. کلاس های زیر را ایجاد نمایید.
package android.vogella.com.retrofitstackoverflow;
// This is used to map the JSON keys to the object by GSON
public class Question {
String title;
String link;
@Override
public String toString() {
return(title);
}
}
package android.vogella.com.retrofitstackoverflow;
import java.util.List;
public class StackOverflowQuestions {
List items;
}
با پیاده سازی interface زیر REST API را برای Retrofit تعریف نمایید.
از آنجایی stackoverflow پاسخ را در یک آبجکت جاسازی می کند، لازم است ساختار داده ای مورد نیاز را از نوع list تعریف نمایید.
package com.vogella.android.retrofitstackoverflow;
import retrofit.Callback;
import retrofit.http.GET;
import retrofit.http.Query;
import retrofit.Call;
public interface StackOverflowAPI {
@GET("/2.2/questions?order=desc&sort=creation&site=stackoverflow")
Call loadQuestions(@Query("tagged") String tags);
}
یک منوی XML مشابه زیر با نام main_menu.xml ایجاد نمایید.
کد کلاس activity خود را طوری ویرایش نمایید که به شما امکان کوئری گرفتن از سوال هایی را بدهد که با رشته ی "android" علامت یا تگ گذاری شده اند.
package com.vogella.android.retrofitstackoverflow; import android.app.Activity; import android.app.ListActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.Window; import android.widget.ArrayAdapter; import android.widget.Toast; import java.util.ArrayList; import retrofit.Call; import retrofit.Callback; import retrofit.GsonConverterFactory; import retrofit.Response; import retrofit.Retrofit; public class MainActivity extends ListActivity implements Callbackتمرین: استفاده از Retrofit برای دسترسی به توابع Github (API) در اندروید{ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); requestWindowFeature(Window.FEATURE_PROGRESS); ArrayAdapter arrayAdapter = new ArrayAdapter (this, android.R.layout.simple_list_item_1, android.R.id.text1, new ArrayList ()); setListAdapter(arrayAdapter); setProgressBarIndeterminateVisibility(true); setProgressBarVisibility(true); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { setProgressBarIndeterminateVisibility(true); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.stackexchange.com") .addConverterFactory(GsonConverterFactory.create()) .build(); // prepare call in Retrofit 2.0 StackOverflowAPI stackOverflowAPI = retrofit.create(StackOverflowAPI.class); Call call = stackOverflowAPI.loadQuestions("android"); //asynchronous call call.enqueue(this); // synchronous call would be with execute, in this case you // would have to perform this outside the main thread // call.execute() // to cancel a running request // call.cancel(); // calls can only be used once but you can easily clone them //Call c = call.clone(); //c.enqueue(this); return true; } @Override public void onResponse(Response response, Retrofit retrofit) { setProgressBarIndeterminateVisibility(false); ArrayAdapter adapter = (ArrayAdapter ) getListAdapter(); adapter.clear(); adapter.addAll(response.body().items); } @Override public void onFailure(Throwable t) { Toast.makeText(MainActivity.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); } }
آموزش تنظیم پروژه
به منظور تست Retrofit، یک اپلیکیشن به نام Retrofit Github ایجاد نمایید. اسم com.vogella.android.retrofitgithub را به عنوان top level package مورد استفاده قرار دهید.
برای استفاده از Retrofit در اپلیکیشن مورد نظر، کتابخانه (dependency) زیر را به فایل build.gradle خود اضافه نمایید.
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
مجوز لازم برای دسترسی به اینترنت را در فایل تنظیمات اپلیکیشن (manifest) تنظیم نمایید.
Interface و کلاس زیر را برای Retrofit API ایجاد نمایید.
package com.vogella.android.retrofitgithub;
// This is used to map the JSON keys to the object by GSON
public class GithubRepo {
String name;
String url;
@Override
public String toString() {
return(name + " " + url);
}
}
package com.vogella.android.retrofitgithub;
// This is used to map the JSON keys to the object by GSON
public class GithubUser {
String login;
String name;
String email;
@Override
public String toString() {
return(login);
}
}
package com.vogella.android.retrofitgithub;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
public interface GithubAPI {
String ENDPOINT = "https://api.github.com";
@GET("/users/{user}")
Call getUser(@Path("user") String user);
@GET("users/{user}/repos")
Call<>> getRepos(@Path("user") String user);
}
package com.vogella.android.retrofitgithub;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class MainActivity extends Activity implements Callback {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View view) {
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(GithubAPI.ENDPOINT)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
GithubAPI githubUserAPI = retrofit.create(GithubAPI.class);
switch (view.getId()) {
case R.id.loadUserData:
// prepare call in Retrofit 2.0
Call callUser = githubUserAPI.getUser("vogella");
//asynchronous call
callUser.enqueue(this);
break;
case R.id.loadRepositories:
Call<>> callRepos = githubUserAPI.getRepos("vogella");
//asynchronous call
callRepos.enqueue(repos);
break;
}
}
Callback repos = new Callback<>>(){
@Override
public void onResponse(Call<>> call, Response<>> response) {
if (response.isSuccessful()) {
List repos = response.body();
StringBuilder builder = new StringBuilder();
for (GithubRepo repo: repos) {
builder.append(repo.name + " " + repo.toString());
}
Toast.makeText(MainActivity.this, builder.toString(), Toast.LENGTH_SHORT).show();
} else
{
Toast.makeText(MainActivity.this, "Error code " + response.code(), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Did not work " + t.getMessage(), Toast.LENGTH_SHORT).show();
}
};
@Override
public void onResponse(Call call, Response response) {
int code = response.code();
if (code == 200) {
GithubUser user = response.body();
Toast.makeText(this, "Got the user: " + user.email, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Did not work: " + String.valueOf(code), Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call call, Throwable t) {
Toast.makeText(this, "Nope", Toast.LENGTH_LONG).show();
}
}
url مقابل https://api.github.com/users/vogellaرا در نوار آدرس مرورگر وارد نمایید. پس از پیمایش به آدرس مذکور، یک کلاس data model و interface با داده های مورد نظر ایجاد کنید. حال این داده ها را با Retrofit خوانده و در یک لیست به نمایش بگذارد.