안녕세계
[라이브러리] Retrofit 1.9 사용법 (Android ↔ Node.js 통신) 본문
[라이브러리] Retrofit 1.9 사용법 (Android ↔ Node.js 통신)
Junhong Kim 2016. 10. 31. 13:40- Retrofit 1.9 를 이용한 Android <-> Node.js 통신 -
[Step 1] Retrofit 라이브러리 추가
Project > Gradel Scripts > build.gradle (Module: app)
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.squareup.retrofit:retrofit:1.9.0'
}
[Step 2] 인터넷 퍼미션 허용
Project > app > manifests > AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
[Step 3] API Service 클래스 생성 (SokmaumService.class)
- POST와 GET 방식에 대해 테스트 URL
public interface SokmaumService {
String API_URL = "EC2_URL";
@FormUrlEncoded
@POST("/posts")
void createPost(@Field("title") String title,
@Field("contents") String contents, CustomObjectCallback<Post> callback);
@GET("/posts/{pid}")
void getPost(@Path("pid") int post_id, CustomObjectCallback<Post> callback);
}
[Step 4] 서버에서 받을 형식을 정의한 클래스 Result.class (예제에서는 result)
public class Result<T> {
T result;
List<T> results;
public T getResult() {
return result;
}
public List<T> getResults() {
return results;
}
}
[Step 5] CustomCallback 만들기
- 이 Callback은 서버에서 보낸 형태의 껍데기 하나 벗겨내는 역할을 합니다. (여기서는 result 라는 껍데기를 벗기는 역할)
(1) 단건: CustomObjectCallback.class
public abstract class CustomObjectCallback<T> implements Callback<Result<T>> {
abstract public void success(T result);
@Override
public void success(Result<T> tResult, Response response) {
success(tResult.getResult());
}
}
(2) 다건: CustomArrayCallback.class
public abstract class CustomArrayCallback<T> implements Callback<Result<T>> {
abstract public void success(List<T> results);
@Override
public void success(Result<T> tResult, Response response) {
success(tResult.getResults());
}
}
[Step 6] Retrofit 1.9 설정
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(SokmaumService.API_URL)
.setConverter(new GsonConverter(new GsonBuilder().create()))
.build();
[Step 7] Retrofit 1.9 사용
(1) POST
restAdapter.create(SokmaumService.class).createPost("hello", "Retrofit", new CustomObjectCallback<Post>() {
@Override
public void success(Post result) {
Log.i("mrv", "작성완료");
Toast.makeText(getApplicationContext(), "작성 성공", Toast.LENGTH_SHORT).show();
}
@Override
public void failure(RetrofitError error) {
Log.i("mrv", "작성실패");
Toast.makeText(getApplicationContext(), "작성 실패", Toast.LENGTH_SHORT).show();
}
});
(2) GET
restAdapter.create(SokmaumService.class).getPost(1, new CustomObjectCallback<Post>() {
@Override
public void success(Post result) {
Log.i("mrv", result.getTitle());
}
@Override
public void failure(RetrofitError error) {
}
});
//--
안녕하세요!
안드로이드 앱을 개발하다보면 서버와의 통신 작업이 많이 필요하게 되는데요
이때 정말 편하게 사용할 수 있는 라이브러리인 Retrofit을 소개해보려고 합니다.
이 글을 작성할 때
생각자유의 안드로이드 이야기 - Retrofit 기본 기능에 대해서 알아보자
이 글을 많이 참조하였습니다!
http://square.github.io/retrofit/
저는 Retrofit을 이용하여 날씨 정보를 가져오는 API 통신을 해보겠습니다.
https://developers.skplanetx.com/apidoc/kor/weather/
SKplanet 에서 제공하는 Weather Planet에서 정보를 받아오겠습니다.
먼저 build.gradle(Module : app) 에 다음과 같이 추가해줍니다.
인터넷 통신을 하기 위해 퍼미션을 추가 해 줍니다.
이로써 Retrofit 을 사용하기 위한 준비가 끝났습니다.
이제 본격적으로 날씨 정보 얻어오기를 달려보겠습니다!
저는 현재날씨(시간별) 데이터를 받아보겠습니다.
Weather Planet 의 현재 날씨 API는 다음과 같은 양식으로 되어있습니다.
Resource URI
http://apis.skplanetx.com/weather/current/hourly?version={version}&lat={lat}&lon={lon}&city={city}&county={county}&village={village}
Protocol - REST
HTTP Method - GET
여기서
http://apis.skplanetx.com/ 은 baseURL
weather/current/hourly 는 현재날씨(시간별)에 해당하는 URL
? 뒤쪽 부분은 변수 명이 됩니다.
이를 이용하여 Interface Class를 선언해 보겠습니다
저는 WeatherRepo 클래스 안에 인터페이스를 선언하여 Call<WeatherRepo> 로 나오게 되었습니다.
WeatherRepo 클래스는 API 통신을 하며 데이터를 받는 객체 클래스로 아래에서 설명드리겠습니다.
버전 정보와 위도, 경도만 필요하기 때문에 country 와 village는 생략하였습니다.
이와 같이
@Headers 에는 필요한 헤더 부분을 ({ ~~ . ~~ }) 형식으로 넣어줄 수 있습니다.
@GET 부분에는 현재날씨(시간별)에 해당하는 URL 을 넣어줍니다.
다음으로 Call입니다.
Call <'주고받을 객체'> '함수명' (@Query ('변수 이름') '자료형' '변수 이름') 형태로 나타나 있는데요
@Query 를 통해 위치가 바뀌어도 동적으로 값을 받아올 수 있습니다!
다음으로는 응답 샘플 코드를 보겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | { "result":{ "message":"성공", "code":9200, "requestUrl":"/weather/current/hourly?lon=&village=도곡동&county=강남구&lat=&city=서울&version=1" }, "common":{ "alertYn":"Y", "stormYn":"N" }, "weather":{ "hourly":[ { "grid":{ "latitude":"37.4870600000", "longitude":"127.0460400000", "city":"서울", "county":"강남구", "village":"도곡동" }, "wind":{ "wdir":"266.00", "wspd":"3.20" }, "precipitation":{ "type":"0", "sinceOntime":"0.00" }, "sky":{ "name":"맑음", "code":"SKY_O01" }, "temperature":{ "tc":"6.80", "tmax":"8.10", "tmin":"-0.90" }, "humidity":"31.00", "lightning":"0", "timeRelease":"2013-11-11 14:00:00" } ] } } | cs |
여기서 저희는 필요한 것만 골라서 받아올 수 있습니다!
갓 구글께서는 JSON을 쉽게 파싱할 수 있도록 GSON 라이브러리를 만들어 주셨습니다.
이를 야무지게 사용해 보겠습니다.
위의 응답 데이터 양식과 아래의 코드를 보면
GSON이 쉽고 편하고 아름답게 파싱해 주는 것을 볼 수 있습니다!
여기서 @SerializedName 어노테이션이 포인트인데요
이 어노테이션을 이용하면 wspd(풍속) 을
@SerializedName("wspd") String windSpeed; 처럼 변수 이름을 바꿔 넣을 수도 있습니다.
응답코드에 hourly 뒤를 보시면 JSONArray 형태로 되어 있는데요
이를 위와 같이 클래스로 만들어 ArrayList<hourly> 형태로 만들어준다면 쉽게 파싱이 가능합니다!
이부분을 잘 몰라서 삽질 했던 기억이 나네요...
다음으로는 위에서 만든 Retrofit interface를 구현해보도록 하겠습니다!
저는 날씨 정보를 가져오는 스레드인
WeatherThread 에서 날씨 정보를 받아오겠습니다.
생성자를 통해 위도와 경도를 받아와
service.get_Weather_retrofit(version, lat, lon) 부분에 값을 넣어줍니다.
요청이 성공적으로 수행되면 onResponse로 진입을 하게 되는데 이곳에서 response.isSuccessful() 로 요청이 성공적으로 이루어 지면
WeatherRepo 에 response.body를 입혀줍니다. response.body 에는 위의 응답 샘플 코드와 같은 정보가 들어있어 이를
GSON으로 파싱 할 수 있을 것입니다.
response.raw 함수로 응답으로 온 http raw 데이터를 볼 수 있습니다.
응답코드가 정상인지 확인한 후
weatherRepo.get~~~ 함수들로 값을 받아와 객체에 저장할 수 있습니다!
Retrofit은 제가 사용한 GET 방법 외에도 POST, PUT 등 다양한 Request 방식을 지원합니다.
여러가지 사용법은 추후 공부를 더 하게되면 추가 해 나가도록 하겠습니다!
이상 Retrofit 사용법 글을 마치겠습니다 감사합니다!
//--
[한글 API 문서]
http://devflow.github.io/retrofit-kr/
http://falinrush.tistory.com/5
http://tiii.tistory.com/9
http://iw90.tistory.com/123
- 끗 -
'Client > Android' 카테고리의 다른 글
[안드로이드] Toolbar (0) | 2017.01.17 |
---|---|
[안드로이드] RecyclerView - Divider 생성 (0) | 2017.01.16 |
[안드로이드] RecyclerView With TabLayout (Feat. ViewPager) (0) | 2017.01.12 |
[라이브러리] Buttef Knife 8.4.0 (0) | 2016.11.25 |
[안드로이드] SimpleDateFormat (날짜형식 변경) (0) | 2016.11.01 |