City At Night

[Android Studio] Retrofit2를 사용하여 Api파싱 본문

Android Studio

[Android Studio] Retrofit2를 사용하여 Api파싱

Wuny 2021. 1. 31. 18:32
728x90
반응형

retrofit2는 OKHTTP + RXJAVA+JSON파싱 라이브러이가 혼합된 라이브러리 이다. 

나는 원래 asyncTask를 사용하여 Json형식으로 넘어오는 API를 파싱하곤 했다. 

아니 난 배울때부터 asyncTask만 배워서 이것밖에 몰랐었다. 

어느날 안드로이드 스튜디오에 들어가보니 

asyncTask의 코드에 줄이 그어져있었다... 그 의미는 안드로이드에서 Deprecate(비추천?) 한 다는 말이기에 다른 대체를 알아보다 Retrofit2를 알게 되었다. 

처음에는 삽질을 무지하게 했지만 한번 사용법을 알고나면 진짜 편하다. 

-------------------------------------------------

저는 jsonplaceholder.typicode.com/users Sample 데이터로 포스팅을 하겠습니다.

Retrofit2는 Interface 클래스에서  내가 원하는 데이터만 Main으로 보낸다. 

Api로 넘어보는 데이터는 DTO클래스에 다 선언해줘야한다. 이런 노가다 수고를 덜어줄 고마운 사이트가 있으니 

하나하나 작성할 필요없이 복붙을 이용하면 빠른 퇴근이 가능하다.

www.jsonschema2pojo.org/

 

------------------------------------------------<추가>----------------

깜빡하고 제일 중요한걸 안적어서 ...추가합니다 ㅜ 이런 실수를..

<menifest.xml>

<uses-permission android:name="android.permission.INTERNET"/>

추가해야합니다!

<build.gradle>

이것도 dependencies에 추가를 해줘야해요

    implementation group: 'com.squareup.retrofit2', name: 'retrofit', version: '2.8.1'
    implementation group: 'com.squareup.retrofit2', name: 'converter-gson', version: '2.8.1' // JSON을 직렬화
    implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6' // 직렬화된 JSON을 객체로 역직렬화

 

 

<UserDTO.java>

public class UserDTO {
    @SerializedName("id")
    @Expose
    private Integer id;
    @SerializedName("name")
    @Expose
    private String name;
    @SerializedName("username")
    @Expose
    private String username;
    @SerializedName("email")
    @Expose
    private String email;
    @SerializedName("address")
    @Expose
    private Address address;
    @SerializedName("phone")
    @Expose
    private String phone;
    @SerializedName("website")
    @Expose
    private String website;
    @SerializedName("company")
    @Expose
    private Company company;


    public class Address {
    
    // 생략 ....

    }

    public class Company {
	// 생략....

    }
    public class Geo {
    // 생략....

}

코드가 너무 길어지니 생략하였다.

<Interfaace.java>

public interface AppInterface {
    @GET("users")
    Call<List<UserDTO>>getAll();
}

https://www.jsonplaceholder.typicode.com/users  이 전체 URI에서 파싱할 URI인 users만 넣어준다.

REST API 라이브러이기 때문에 POST,PUT,DELETE 가능합니다.

저는 Call<List<UserDTO>>getAll()을 선언하여 모든 데이터를 가져오게 했다.

@Query을 사용하여 내가 원하는 값만 뽑아내거나 @Path를 사용하여 URL로 데이터를 뽑아 낼 수 있지만

필자는 모든 데이터를 가져온 다음 필요한 데이터만 파싱하는게 편하기에 저렇게 했다.

 

<Main.Activity.java>

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Retrofit retrofit = new Retrofit.Builder().baseUrl("https://jsonplaceholder.typicode.com/")
                .addConverterFactory(GsonConverterFactory.create()).build();
        AppInterface appInterface = retrofit.create(AppInterface.class);
        Call<List<UserDTO>> call = appInterface.getAll();
        call.enqueue(new Callback<List<UserDTO>>() {
            @Override
            public void onResponse(Call<List<UserDTO>> call, Response<List<UserDTO>> response) {
                if(response.isSuccessful()){
                    List<UserDTO> userDTO = response.body();
                    Log.d("##","Successed! , Result \n" + userDTO.toString());

                    for(int i=0; i < userDTO.size(); i++){
                        if(userDTO.get(i).getId() == 1){
                            System.out.println("ID : " + userDTO.get(i).getId());
                            System.out.println("Name : " + userDTO.get(i).getName());
                            System.out.println("userName : " + userDTO.get(i).getUsername());
                            System.out.println("Email : " + userDTO.get(i).getEmail());
                            System.out.println("Address : " + userDTO.get(i).getAddress().getStreet() + userDTO.get(i).getAddress().getSuite());
                            System.out.println("phon : " + userDTO.get(i).getPhone());
                            System.out.println("Company Name : " + userDTO.get(i).getCompany().getName());
                        }
                    }
                }
            }

            @Override
            public void onFailure(Call<List<UserDTO>> call, Throwable t) {
                Log.d("","onFailure: "+t.getLocalizedMessage());
            }
        });

    }
}

baseUrl에는 내가 파싱하고자하는 사이트의 base만 넣어둔다. 나머지 URI는 인터페이스에서 선언해줄것이다.

무조건 '/' 로 끝나야한다

예시로 ID가 1인 데이터만 뽑아내기 위해서 조건문을 사용하였다 .

Interface에서 query문을 사용하여 바로 Id가 1인 데이터를 뽑아 낼 수 있지만 나는 이것저것 데이터를 편하게 뽑아내고 가지고 노는걸 좋아하기에 다 가져왔다. 편한데로 쓰면 될듯..

내가 원하는데로 잘 나온다 

728x90
반응형
Comments