반응형

오늘도 삽질을 했습니다.....

난이도가 어려워질수록 한번에 되는게 없네요

RestAPI까지만 혼자 공부하고 학교 취업 커뮤니티에서 알게된 같은과 선배님이랑 프로젝트 하나 진행해보려 했는데, 언제쯤 할 수 있을지 모르겠네요 ㅠ_ㅠ

1. 구현하고자 하는 것

아래 링크의 날씨 어플을 Retrofit을 이용해서 "REST"하게 오픈API를 사용해보려 했는데, 실패했습니다.

 

[안드로이드 스튜디오 독학#27] 현재 날씨 어플

Thread와 Network를 공부하고 개념을 정리하기 전에 간단한 예제를 구현하려고 했는데, 생각지 못한 에러가 여러곳에서 발생했고, 이를 해결하다보니 게시물을 올리는 시간이 늦춰졌다. 스레드를

seminzzang.tistory.com

2. 소스코드

MainActivity.java

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
54
55
56
57
58
package com.example.restapiexample;
 
import androidx.appcompat.app.AppCompatActivity;
 
import android.os.Bundle;
import android.widget.TextView;
 
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
 
public class MainActivity extends AppCompatActivity {
    private TextView tv_weather;
 
    private RetrofitClient retrofitClient;
    private RetrofitInterface retrofitInterface;
 
    private String MyKey = "J1uWhMdL85rUtm1%2FogRUgAehBm4pAZ2QJBmZ8ytsj9q5VPkKoPyTuUWItYfi5LAXgTA%2Bmn2ERVnNZDQsfwYxpg%3D%3D";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        tv_weather = (TextView)findViewById(R.id.tv_weather);
 
        try {
            retrofitClient = RetrofitClient.getInstance();
            retrofitInterface = RetrofitClient.getRetrofitInterface();
 
            retrofitInterface.getWeather(MyKey,
                    "1",
                    "8",
                    "XML",
                    "20210206",
                    "1500",
                    "59",
                    "122").enqueue(new Callback<Codebeautify>() {
                @Override
                public void onResponse(Call<Codebeautify> call, Response<Codebeautify> response) {
 
                }
 
                @Override
                public void onFailure(Call<Codebeautify> call, Throwable t) {
 
                }
            });
 
        }catch (Exception e){
            tv_weather.setText(e.getMessage());
        }
 
 
    }
}
 
 
cs

 

Codebeautify.java ( Xml 데이터를 담을 데이터 클래스 )

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
public class Codebeautify {
 Response ResponseObject;
 
 
 // Getter Methods 
 
 public Response getResponse() {
  return ResponseObject;
 }
 
 // Setter Methods 
 
 public void setResponse(Response responseObject) {
  this.ResponseObject = responseObject;
 }
}
public class Response {
 Header HeaderObject;
 Body BodyObject;
 
 
 // Getter Methods 
 
 public Header getHeader() {
  return HeaderObject;
 }
 
 public Body getBody() {
  return BodyObject;
 }
 
 // Setter Methods 
 
 public void setHeader(Header headerObject) {
  this.HeaderObject = headerObject;
 }
 
 public void setBody(Body bodyObject) {
  this.BodyObject = bodyObject;
 }
}
public class Body {
 private String dataType;
 Items ItemsObject;
 private String numOfRows;
 private String pageNo;
 private String totalCount;
 
 
 // Getter Methods 
 
 public String getDataType() {
  return dataType;
 }
 
 public Items getItems() {
  return ItemsObject;
 }
 
 public String getNumOfRows() {
  return numOfRows;
 }
 
 public String getPageNo() {
  return pageNo;
 }
 
 public String getTotalCount() {
  return totalCount;
 }
 
 // Setter Methods 
 
 public void setDataType(String dataType) {
  this.dataType = dataType;
 }
 
 public void setItems(Items itemsObject) {
  this.ItemsObject = itemsObject;
 }
 
 public void setNumOfRows(String numOfRows) {
  this.numOfRows = numOfRows;
 }
 
 public void setPageNo(String pageNo) {
  this.pageNo = pageNo;
 }
 
 public void setTotalCount(String totalCount) {
  this.totalCount = totalCount;
 }
}
public class Items {
 ArrayList < Object > item = new ArrayList < Object > ();
 
 
 // Getter Methods 
 
 
 
 // Setter Methods 
 
 
}
public class Header {
 private String resultCode;
 private String resultMsg;
 
 
 // Getter Methods 
 
 public String getResultCode() {
  return resultCode;
 }
 
 public String getResultMsg() {
  return resultMsg;
 }
 
 // Setter Methods 
 
 public void setResultCode(String resultCode) {
  this.resultCode = resultCode;
 }
 
 public void setResultMsg(String resultMsg) {
  this.resultMsg = resultMsg;
 }
}
cs

RetrofitClient.java

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
package com.example.restapiexample;
 
import retrofit2.Retrofit;
import retrofit2.converter.jaxb.JaxbConverterFactory;
 
public class RetrofitClient {
    private static RetrofitClient instance = null;
    private static RetrofitInterface retrofitInterface;
    private static String baseUrl = "http://apis.data.go.kr/";
 
    private RetrofitClient(){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(JaxbConverterFactory.create())
                .build();
        retrofitInterface = retrofit.create(RetrofitInterface.class);
    }
 
    public static RetrofitClient getInstance(){
        if(instance == null){
            instance = new RetrofitClient();
        }
        return instance;
    }
 
    public static RetrofitInterface getRetrofitInterface() {
        return retrofitInterface;
    }
}
 
cs

RetrofitInterface.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example.restapiexample;
 
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
 
public interface RetrofitInterface {
 
    @GET("http://apis.data.go.kr/1360000/VilageFcstInfoService/getUltraSrtNcst")
    Call<Codebeautify> getWeather(@Query("serviceKey"String serviceKey,
                              @Query("pageNo"String pageNo,
                              @Query("numOfRows"String numOfRows,
                              @Query("dataType"String dataType,
                              @Query("base_date"String base_date,
                              @Query("base_time"String base_time,
                              @Query("nx"String nx,
                              @Query("ny"String ny);
}
 
cs

3. 지금까지 시도 해본 것

 1) build.gradle(Module: app) 에서 다음 내용을 implementation했고, retrofit, okhttp, jaxb가 제대로 implementation된 것을 MainActivity에서 확인했습니다.

1
2
3
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.squareup.retrofit2:converter-jaxb:2.9.0'
cs

 2) 처음에 baseUrl에 Url 전체를 입력하고 @GET을 공백으로 했는데, Error가 발생했고 try catch문을 통해 baseUrl은 '/'로 끝나야 한다는 것을 알고 수정했습니다.

 3) URL이 문제인가 싶어 URL을 확인했고, URL이 잘못된 것이 아니라는 것은 파악했습니다.

 4) URL을 일부로 오타를 내서 Exception을 확인했는데, 정상적인 URL과 동일한 에러 메세지를 받는 것을 확인했습니다.

 5) Data Class를 잘못 만든건가 싶어서 다른 블로그와 github를 참조하여 비교해보았고, Class를 잘못 만든것은 아니라 판단했습니다. 자료를 찾던 중에 xml->java class 변환 사이트를 찾아 해당 사이트를 이용하기도 해봤습니다.

 

XML to JAVA Converter: Convert XML to JAVA format

 

codebeautify.org

 6) Get 메세지를 잘못 구현했다 판단해서 코드를 수정했습니다.( 위의 소스코드 참고)

4. 내가 생각하는 문제점

 1) XML 받을 데이터 클래스의 문제

-> xml을 java class로 변환해주는 사이트를 찾았고, 이를 통해 변환해주었습니다. 그리고 다른 예제들을 보면서 클래스를 비교해봤지만 딱히 에러가 생길만한 부분을 찾지 못했습니다.

 2) Retrofit 설정 오류

 -> 이것 역시 비교해보았고, OpenAPI를 받는 URL이 XML타입의 데이터를 반환한다는 것을 확인했습니다.

 3) unmarshal의 문제

 -> unmarshal은 xml을 java로 역직렬화 하는 과정으로 데이터를 받을 때 xml타입으로 받기 때문에 딱히 필요없다고 파악했습니다.

 4) jaxb의 문제

 -> 에러 메세지를 보면 위의 사진처럼 나타나는데, url의 문제가 아니라면 jaxb를 사용하면서 설정의 문제나 혹은 다른 문제가 있을 것이라 생각합니다.

 5) baseUrl? GetURL??

 -> baseUrl에서 초기 url을 지정하고 Get에서 Url을 한번 더 지정하는데 이게 문제인가 싶어서 Get의 URL을 수정해보았지만 똑같은 에러를 얻었습니다.

반응형

+ Recent posts