반응형
구글 API 적용 중 일반 JSON 이 아닌 JSONP 형식의 데이터 파싱할 상황 발생
GsonConverterFactory 적용하면 JSON 형식이 아니라며 오류 발생함
일반적인 JSON 형식
{
"cursor": {
"currentPageIndex": 0,
"estimatedResultCount": "0"
},
"context": {
"title": "aaa",
"total_results": "0"
},
"google": {
"url": "https://www.xxx.com?client=xxxxxxxxx"
}
}
JSONP 형식 : callback 함수명이 감싸고 있는 형태
google({
"cursor": {
"currentPageIndex": 0,
"estimatedResultCount": "0"
},
"context": {
"title": "aaa",
"total_results": "0"
},
"google": {
"url": "https://www.xxx.com?client=xxxxxxxxx"
}
});
정상적으로 파싱 하려면 콜백 관련 문자열은 제거해줘야 함
커스텀 컨버터 생성 후 레트로핏에 적용
1. GsonPConverterFactory.java 생성
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
public final class GsonPConverterFactory extends Converter.Factory {
Gson gson;
public GsonPConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonPResponseBodyConverter%3C%3E(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations,
Annotation[] methodAnnotations,
Retrofit retrofit) {
return null;
}
}
2. GsonPResponseBodyConverter.java 생성
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import java.io.IOException;
import java.io.Reader;
import okhttp3.ResponseBody;
import retrofit2.Converter;
final public class GsonPResponseBodyConverter implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter adapter;
GsonPResponseBodyConverter(Gson gson, TypeAdapter adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public T convert(ResponseBody value) throws IOException {
Reader reader = value.charStream();
int item = reader.read();
while(item != '(' && item != -1) {
item = reader.read();
}
JsonReader jsonReader = gson.newJsonReader(reader);
try {
return adapter.read(jsonReader);
} finally {
reader.close();
}
}
}
3. 레트로핏 적용
gson = new GsonBuilder()
.setLenient()
.create();
retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(new GsonPConverterFactory(gson))
.build();
반응형
'Android' 카테고리의 다른 글
[Android] https 요청 시 ssl 인증서 오류 (0) | 2023.03.28 |
---|---|
[Android] Notification 에 RemoteViews 사용 시 이미지 삽입 (0) | 2019.07.23 |
[android] YouTubePlayerFragment fullscreen error 유튜브 API 전체화면 오류 (0) | 2019.06.04 |
[Android Fcm]FirebaseApp name [DEFAULT] already exists! (0) | 2019.05.27 |
안드로이드 전화번호부에 저장된 이름 가져오기 (0) | 2014.03.13 |