최근에 Retrofit을 이용한 프로젝트를 했는데, 까먹을까봐 글을 남긴다. 원래는 Volley로 하려고 했는데, Retrofit이 더 좋다고 해서 써봤다.
dependencies { compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4' compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4' }
일단 gradle에 관련 라이브러리를 추가한다.
public class BaseService { protected static Object retrofit(Class<?> className) { String host = "http://test.susemi99.kr/"; Retrofit retrofit = new Retrofit.Builder().baseUrl(host).addConverterFactory(GsonConverterFactory.create()).build(); // Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create(); // return new Retrofit.Builder().baseUrl(host).addConverterFactory(GsonConverterFactory.create(gson)).build(); // return new Retrofit.Builder().baseUrl(host).addConverterFactory(GsonConverterFactory.create()).client(client()).build(); // return new Retrofit.Builder().baseUrl(host).addConverterFactory(GsonConverterFactory.create(gson)).client(client()).build(); return retrofit.create(className); } // private static OkHttpClient client() // { // return new OkHttpClient.Builder().addInterceptor(new Interceptor() // { // @Override // public Response intercept(Chain chain) throws IOException // { // Request original = chain.request(); // Request.Builder requestBuilder = original.newBuilder().method(original.method(), original.body()); // // String token = "sample-token"; // if (!TextUtils.isEmpty(token)) // requestBuilder.header("Authorization", token); // // String locale = Locale.getDefault().getLanguage(); // requestBuilder.header("X-Locale", locale); // // Request request = requestBuilder.build(); // return chain.proceed(request); // } // }).build(); // } }
Retrofit의 기본이 되는 클래스를 만든다.
간단하게 쓰려면 따로 안해줘도 되는데 기본적인 날짜 포맷을 바꾸거나, 매 호출마다 특정한 헤더를 넣으려면 무언가를 더 해줘야 한다.
프로젝트 할 때에는 헤더에 Authrization 을 넣는 걸 찾는데 조금 오래 걸렸다.
public final class ListService extends BaseService { public static ListAPI api() { return (ListAPI) retrofit(ListAPI.class); } public interface ListAPI { @GET("{name}.json") Call<Json1Item> json1(@Path("name") String name); @GET("{name}.json") Call<Json1Item[]> json2(@Path("name") String name); @GET("{name}.json") Call<Json3Item> json3(@Path("name") String name); @GET("{name}.json") Call<Json4Item> json4(@Path("name") String name); } }
그 다음에는 실제로 호출할 api를 갖고 있는 클래스를 만든다.
GET/POST 같은 방식과 url 만들기용 값을 이 곳에서 처리한다.
http://abc.com/asdf?name=qqqq 라는 url이라면 asdf는 @Path로 해야하고, name=qqqq는 @Body로 해야한다.
자세한 정보는 http://square.github.io/retrofit 에 가면 있다.
public class Json1Item { public String name; public String url; }
public class Json3Item { public List<Json1Item> result; }
public class Json4Item { public Json1Item result; }
값을 넣을 모델들을 만들어 준다.
파싱은 Gson이 알아서 해준다.
/* { "name":"title1", "url":"http://google.co.kr/1" } */ private void callJsonType1() { ListService.api().json1("jackson1").enqueue(new Callback<Json1Item>() { @Override public void onResponse(Call<Json1Item> call, Response<Json1Item> response) { if (response != null && response.isSuccess() && response.body() != null) { Json1Item type = response.body(); Log.i("MainActivity | callJsonType1", type.name + ", " + type.url); } } @Override public void onFailure(Call<Json1Item> call, Throwable t) { t.printStackTrace(); } }); }
/* [ { "name":"title1", "url":"http://google.co.kr/1" }, { "name":"title2", "url":"http://google.co.kr/2" } ] */ private void callJsonType2() { ListService.api().json2("jackson2").enqueue(new Callback<Json1Item[]>() { @Override public void onResponse(Call<Json1Item[]> call, Response<Json1Item[]> response) { if (response != null && response.isSuccess() && response.body() != null) { Json1Item[] type2 = response.body(); for (Json1Item type : type2) { Log.i("MainActivity | callJsonType2", type.name + ", " + type.url); } } } @Override public void onFailure(Call<Json1Item[]> call, Throwable t) { t.printStackTrace(); } }); }
/* { "result":[ { "name":"title1", "url":"http://google.co.kr/1" }, { "name":"title2", "url":"http://google.co.kr/2" }, { "name":"title3", "url":"http://google.co.kr/3" }] } */ private void callJsonType3() { ListService.api().json3("jackson3").enqueue(new Callback<Json3Item>() { @Override public void onResponse(Call<Json3Item> call, Response<Json3Item> response) { if (response != null && response.isSuccess() && response.body() != null) { Json3Item type3 = response.body(); for (Json1Item type : type3.result) { Log.i("MainActivity | callJsonType3", type.name + ", " + type.url); } } } @Override public void onFailure(Call<Json3Item> call, Throwable t) { t.printStackTrace(); } }); }
/* { "result": { "name":"title1", "url":"http://google.co.kr/1" } } */ private void callJsonType4() { ListService.api().json4("jackson4").enqueue(new Callback<Json4Item>() { @Override public void onResponse(Call<Json4Item> call, Response<Json4Item> response) { if (response != null && response.isSuccess() && response.body() != null) { Json4Item type = response.body(); Log.i("MainActivity | callJsonType4", type.result.name + ", " + type.result.url); } } @Override public void onFailure(Call<Json4Item> call, Throwable t) { t.printStackTrace(); } }); }
모양에 맞춰서 작업하면 된다.
써보니까 Volley보다는 좀 더 편한 것 같다.
code: https://github.com/susemi99/RetrofitSample