gson 을 사용 하여 Retrofit 2 분석 서버 에 맞 춰 되 돌려 줍 니 다.

9054 단어 android
프로젝트 는 Retrofit 2+rxjava 2+gson 처리 네트워크 요청 의 데이터 처 리 를 사 용 했 습 니 다.여 기 는 주로 gson 부분 을 소개 합 니 다.
설정
retrofit 2 에는 전문 적 인 converter 가 있 습 니 다.의존 하면 gs on 을 사용 할 수 있 습 니 다.
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

그리고 retrofit 클래스 를 새로 만 들 때 addConverterFactory 가 필요 합 니 다.특정한 Gson 을 사용 하지 않 아 도 됩 니 다.예 를 들 어 자신의 TypeAdpter 특수 처 리 를 추가 하지 않 으 면 gs on 대상 을 전송 하지 않 아 도 됩 니 다.factory 는 스스로 새로 만 들 것 입 니 다.
@Singleton
@Provides
Retrofit provideRetrofit(OkHttpClient client, Gson gson){
    return new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
            .client(client)
            .build();
}

이렇게 gs on 은 초보 적 으로 설정 되 었 습 니 다.
2.gson 을 사용 합 니 다.
1.서버 데 이 터 를 분석 하여 대응 하 는 bean 파일 을 작성 합 니 다.

이 bean 은 json 구조 에 대응 하 는{"data":[],"msg":","status":0}입 니 다.
되 돌아 오 는 데이터 이름과 bean 파일 의 이름 이 다 르 면@SerializedName 의 value 값 을 설정 하여 받 아들 일 수 있 습 니 다.
같은 bean 의 같은 데 이 터 는 두 가지 반환 방식 이 있 습 니 다.예 를 들 어 status 와 Status 는 alternate 를 설정 하여 특수 처리 할 수 있 습 니 다.
여기 data 의 데 이 터 는 범 형 을 사용 하면 서로 다른 상황 의 범 형 끼 워 넣 기 에 따라 json 데 이 터 를 처리 할 수 있 습 니 다.예 를 들 어 Bean>은 여러 층 을 끼 워 넣 어 서로 다른 수 요 를 만족 시 키 고 bean 재 활용 의 목적 을 달성 할 수 있 습 니 다.
2.해석
그리고 Retrofit 2 설정 에서 인터페이스의 귀환 을 명기 합 니 다.
public class Bean<T> {

    private String msg;
    @SerializedName(value = "status", alternate = {"Status"})
    private int resultCode;
    @SerializedName("data")
    private T result;
}

Result 클래스 는?
com.jakewharton.retrofit2.adapter.
rxjava 2 패키지 가 제공 하 는 통 일 된 데이터 반환 클래스 입 니 다.
방문 에 성공 한 후에 우 리 는 얻 을 수 있다.
@FormUrlEncoded
@POST(value = "login.html")
Observable>> login(@Field("token") String token, @Field("username") String user, @Field("password") String passWord);

통과 하 다.
Result      ,           。

빈 상 대 를 얻다.
3.복잡 한 상황 처리
구체 적 인 업무 처리 과정 에서 같은 필드 를 만 나 서로 다른 상황 에서 서버 가 서로 다른 유형의 상황 을 되 돌려 줍 니 다.
예 를 들 어 위의 bean 중의 data 데 이 터 는 서로 다른 상황 에서 jsonobject 일 수도 있 고 String 일 수도 있 고 jsonArray 일 수도 있 습 니 다.
해결 방법:
1.data 를 Object 형식 으로 정의 할 수 있 습 니 다.
2.상기 에서 bean 은 하나의 통 일 된 케이스 로 서 일부 서버 가 돌아 오 는 상 태 를 저장 하 는 것 이 고 data 에서 구체 적 인 업무 데이터 이기 때문에 data 는 범 형 으로 설정 하여 서로 다른 상황 을 나타 내야 한다.
데이터 개체.
이 럴 때 는 Gson 이 제공 하 는 걸 로 할 수 있어 요.
TypeAdapter 또는 JSonDeserializer,JSonSerializer 가 특수 처 리 를 합 니 다.
TypeAdater 는 상대 적 으로 복잡 하 게 사용 되 어 직렬 화 와 반 직렬 화 두 가지 상황 을 처리 할 수 있 습 니 다.
JSonDeserializer,JSonSerializer 는 각각 반 직렬 화 와 직렬 화 상황 을 처리 하 는 데 사용 되 기 쉬 우 나 일부 성능 을 희생 할 수 있다.
서버 측의 반환 데 이 터 를 주로 처리 하기 때문에 JSonDeserializer 를 사용 하여 특수 처 리 를 선택 합 니 다.
Bean<T> b =  result.response().body();
public class BeanTypeDeserializer implements JsonDeserializer {
    @Override
    public Bean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return new
Bean<>(obj.get(
"msg"
).getAsString()
,
obj.get(
"status"
).getAsInt()
,new
Object())
; }} 비록 bean 은 범 형 을 가지 고 있 지만 컴 파일 하 는 동안 범 형 은 지 워 집 니 다.여 기 는 빈 의 범 형 이 확정 되 지 않 는 한>이라는 형식 으로 쓸 필요 가 없습니다.예 를 들 어>이런 형식 입 니 다.
제 이 슨 엘 리 먼 트 는 제 이 슨 데이터 입 니 다.
Type 은 데 이 터 를 처리 하 는 유형 입 니 다.여 기 는 Bean 의 형식 이 어야 합 니 다.XXX 는 data 의 구체 적 인 유형 입 니 다.
JsonDeserializationContext  역 직렬 화 된 문맥 입 니 다.
위 에서 한 것 은 간단 한 처리 입 니 다.되 돌아 오 는 data 데 이 터 를 무시 하고 Object 를 전 달 했 습 니 다.이것 은 분명히 수 요 를 만족 시 킬 수 없다.
data 의 데 이 터 는 다양한 유형 이기 때문에 우리 가 일일이 처리 할 수 없습니다.
여 기 는 Json Deserialization Context 를 사용 하여 data 중의 json 을 다시 Gson 에 게 맡 겨 진일보 한 처 리 를 해 야 합 니 다.이것 은 인터페이스 대상 에 한 가지 방법 만 있 습 니 다.
 
  
	JsonObject obj = json.getAsJsonObject();
jsonElement 데 이 터 를 전송 해 야 합 니 다.Type(우리 가 원 하 는 클래스,즉 이 방법의 반환 T 유형)
jsonElement 는 obj.get()을 통 해 얻 을 수 있 습 니 다.
한편,Type 은 이 상황 에서 확실 하지 않 습 니 다.처음에 저 는 T 에 들 어 가 는 것 을 고려 했 고 Gson 이 제공 하 는 TypeToken 을 통 해 얻 었 습 니 다.
public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseException;
안 타 깝 게 도 이것 은 정상적으로 작 동 하지 못 합 니 다.왜냐하면 T 는 컴 파일 할 때 이미 지 워 졌 고 우 리 는 new 에 있 기 때 문 입 니 다. 
BeanTypeDeserializer 는 T 의 구체 적 인 클래스 에 들 어 갈 수 없습니다.실행 중 에 이 T 는 여러 가지 유형 일 것 입 니 다.
여기 서 우 리 는 들 어 오 는 type:of T 를 사용 해 야 합 니 다.정확 한 해결 방법 은:
public class BeanTypeDeserializer<T> implements JsonDeserializerT>> {
    @Override
    public Bean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject obj = json.getAsJsonObject();
        context.deserialize(obj.get("data"), new TypeToken<T>() {}.getType());
}  

최종 해결 방법:
4.567913.저 는 status 가 0 이 아 닐 때 서버 가 정상적으로 돌아 오지 않 는 다 는 것 을 의미 하기 때문에 data 의 데 이 터 를 처리 하지 않 습 니 다.그러면 실 수 를 피 할 수 있 습 니 다.
BeanTypeDeserializer 설정
context.deserialize(obj.get("data"), ((ParameterizedType) typeOfT).getActualTypeArguments()[0])
registerTypeAdapter 방법 호출
타 입 은 등록 해서 그 종 류 를 처리 하 는 것 이 고 그 다음은 우리 의 처리 류 입 니 다.
여기 서 사용 할 수 있 으 니까.
TypeAdapter 또는 JSonDeserializer,JSonSerializer,Gson 은 Object 를 사용 하여 수신 합 니 다.
이상 은 제 가 Gson 설정 Retrofit 2 로 네트워크 를 되 돌려 주 는 모든 사용 방식 을 사용 하고 있 습 니 다.제 가 만난 모든 상황 을 잠시 해결 할 수 있 습 니 다.다른 특별한 상황 이 있다 면 댓 글로 토론 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기