티스토리 뷰

안드로이드에서 서버와 REST API 통신을 할 때 비동기 쓰레드 처리를 내부적으로 해주는 라이브러리 Retrofit를 이용해 테스트 통신 앱을 만들어 보았다!



#1 Retrofit 의존성 추가하기

app > open module settings > dependencies 탭에서 왼쪽 아래 추가 버튼으로 retrofit을 검색해 아래 두 가지를 추가한다.

com.squareup.retrofit2:retrofit:2.1.0

com.squareup.retrofil2:converter-gson:2.1.0


#2 인터페이스 생성

1
2
3
4
5
6
7
8
9
10
import java.util.List;
 
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
 
public interface GetService {
    @GET("/test/{position}")
    Call<List<Dummy>> listDummies(@Path("position"String position);
}
cs


Dummy라는 객체 리스트를 서버에 GET 요청으로 받아올 예정이다. 

position 을 파라미터로 넣어주어 position값에 따라 받아오는 데이터에 차이를 줘 보려고 한다.


#3 Dummy 클래스 

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
public class Dummy {
    String id;
    String content;
 
    public String getId() {
        return id;
    }
 
    public void setId(String id) {
        this.id = id;
    }
 
    public String getContent() {
        return content;
    }
 
    public void setContent(String content) {
        this.content = content;
    }
 
    @Override
    public String toString() {
        return "ID: "+id+", Content: "+content;
    }
}
cs

Dummy 클래스는 받아오는 JSON 데이터의 속성이름과 똑같이 매핑을 해야 하는데 서버에서 아래와 같이 데이터가 들어오기 때문에 Dummy에서도 id, content를 가진다.
1
2
3
4
{
    id: 'id',
    content'content'
}
cs


#4 액티비티에서 Retrofit 정의

액티비티의 OnCreate에서 Retrofit을 정의한다. URL을 정하고 Converter를 위에서 가져온 GSON으로 정의를 하는데

이전 버전에서는 기본이 GSON이어서 다시 정의할 필요가 없었지만 현재는 기본 설정로 ResponseBody로 되어 있어 GET으로 받은 JSON 데이터를 변환하지 못하고 에러가 났다. 

위에서 정의했던 GetService인터페이스를 구현하고, 

7번줄 Call이 동기 또는 비동기로 HTTP 요청을 보내는 역할을 한다. 

8번줄에서 dummies는 콜백함수로 아래에서 정의하고 있다.

1
2
3
4
5
6
7
8
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(BASE) //http://192.168.0.3:3001 서버 호스트
    .addConverterFactory(GsonConverterFactory.create())
    .build();
 
GetService service = retrofit.create(GetService.class);
Call<List<Dummy>> call = service.listDummies("5");
call.enqueue(dummies);
cs

#5 요청 결과 콜백 구현

요청 결과로 Dummy리스트를 받아오는 콜백 함수를 구현한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Callback dummies = new Callback<List<Dummy>>(){
 
    @Override
    public void onResponse(Call<List<Dummy>> call, Response<List<Dummy>> response) {
        if (response.isSuccessful()) {
            List<Dummy> dummies = response.body();
            StringBuilder builder = new StringBuilder();
            for (Dummy dummy: dummies) {
                builder.append(dummy.toString()+"\n");
            }
            info.setText(builder.toString());
        } else
        {
            info.setText("Fail, "+ String.valueOf(response.code()));
        }
 
    }
 
    @Override
    public void onFailure(Call<List<Dummy>> call, Throwable t) {
        info.setText("Fail");
    }
};
cs



#6 액티비티 전체 코드

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
45
46
47
48
49
50
51
52
53
public class MainActivity extends AppCompatActivity {
    private static final String BASE = "http://192.168.0.69:3001";
 
    EditText position;
    Button getButton;
    TextView info;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        postion = (EditText) findViewById(R.id.position);
        info = (TextView) findViewById(R.id.info);
        getButton = (Button) findViewById(R.id.button);
        getButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Retrofit retrofit = new Retrofit.Builder()
                        .baseUrl(BASE)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();
 
                GetService service = retrofit.create(GetService.class);
                Call<List<Dummy>> call = service.listDummies("5");
                call.enqueue(dummies);
            }
        });
 
    }
 
    Callback dummies = new Callback<List<Dummy>>(){
 
        @Override
        public void onResponse(Call<List<Dummy>> call, Response<List<Dummy>> response) {
            if (response.isSuccessful()) {
                List<Dummy> dummies = response.body();
                StringBuilder builder = new StringBuilder();
                for (Dummy dummy: dummies) {
                    builder.append(dummy.toString()+"\n");
                }
                info.setText(builder.toString());
            } else
            {
                info.setText("Fail, "+ String.valueOf(response.code()));
            }
        }
 
        @Override
        public void onFailure(Call<List<Dummy>> call, Throwable t) {
            info.setText("Fail");
        }
    };
}
cs

#7 테스트 서버 만들기

node.js로 테스트 서버를 만들기 위해 우선 프로젝트르 생성한다.
1
npm init
cs

express, body-parser 설치

1
2
npm install express --save
npm install body-parser --save
cs


index.js 생성

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
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
 
app.use(bodyParser.json());
app.get('/'function(req, res) {
        res.send('Hello World');
});
 
app.get('/test/:position'function(req, res) {
//받은 position 수많큼 객체를 생성해서 JSON 배열로 리턴
        var position = req.params.position;
        console.log(req.params.position);
        var id = 'imcreator ';
        var content= 'hello world! ';
        var results = [];
        for(var i = 0; i<position; i++){
                results.push({
                        id: id + i,
                        contentcontent + i
                });
        }
        res.json(results);
});
 
app.listen(3001function() {
        console.log('Example app listend on port 3001!');
});
cs

1
node index.js
cs
받아온 Dummy 데이터 리스트를 출력하는 모습을 확인했다!



참고문헌

Retrofit, https://square.github.io/retrofit/

Retrofit 또 다른 튜토리얼, http://www.vogella.com/tutorials/Retrofit/article.html

Unable to chttp://stackoverflow.com/questions/34315499/unable-to-create-converter-for-java-util-list-retrofit-2-0-0-beta2

댓글