[android] Retrofit Sample

최근에 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