Gson 해석 빈 문자열 처리 방법

앞말
실제 개발 프로젝트에서 서버는 빈 문자열 ""을 반환 결과로 빈값을 표시하는 경우가 많지만 Gson에서 문제가 발생할 수 있습니다. 만약 이 데이터의 유형이 문자열이 아니라면 Gson 해석은 오류가 발생합니다.
제이슨 이상 상황
먼저 백스테이지에서 돌아온 제이슨을 보겠습니다.
정상적인 상황에서 json:

{
 "code":0,
 "msg":"ok",
 "data":{
  "id":5638,
  "newsId":5638
 }
}
데이터 섹션에 해당하는 엔티티 클래스:

public class JsonBean {
 private int id;
 private int newsId;

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public int getNewsId() {
  return newsId;
 }

 public void setNewsId(int newsId) {
  this.newsId = newsId;
 }
}
예외 json(백그라운드 데이터베이스 newsid 필드에서 해당 데이터가 조회되지 않음):

{
 "code":0,
 "msg":"ok",
 "data":{
  "id":5638,
  "newsId":""
 }
}
이렇게 하면 Gson이 해석할 때 해석 오류의 이상을 던지고 앱이 붕괴됩니다. 왜냐하면 "를 int로 바꿀 수 없기 때문입니다.
json 이상 처리
백그라운드에서 되돌아오는 json이 이상할 때도 성공적으로 해석될 수 있기를 기대합니다. 빈 값은 기본값으로 변환됩니다. 예를 들어 newsId=0;여기서 백그라운드 개발자를 배제하고 출력할 때 교정해 드릴게요. 아니면 자기 자신에게 의지해야 돼요.
우리는 int 값에 대한 형식 변환기를 작성합니다. Gson의 JsonSerializer<T> 인터페이스와 JsonDeserializer<T>, 즉 서열화와 반서열화 인터페이스를 실현해야 합니다.

public class IntegerDefault0Adapter implements JsonSerializer<Integer>, JsonDeserializer<Integer> {
 @Override
 public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
   throws JsonParseException {
  try {
   if (json.getAsString().equals("") || json.getAsString().equals("null")) {// int , "" null, 0
    return 0;
   }
  } catch (Exception ignore) {
  }
  try {
   return json.getAsInt();
  } catch (NumberFormatException e) {
   throw new JsonSyntaxException(e);
  }
 }

 @Override
 public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
  return new JsonPrimitive(src);
 }
}
동리 Long 및 Double 유형
double=>

public class DoubleDefault0Adapter implements JsonSerializer<Double>, JsonDeserializer<Double> {
 @Override
 public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
  try {
   if (json.getAsString().equals("") || json.getAsString().equals("null")) {// double , "" null, 0.00
    return 0.00;
  }
   } catch (Exception ignore) {
  }
  try {
   return json.getAsDouble();
  } catch (NumberFormatException e) {
   throw new JsonSyntaxException(e);
  }
 }

 @Override
 public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
  return new JsonPrimitive(src);
 }
}
long=>

public class LongDefault0Adapter implements JsonSerializer<Long>, JsonDeserializer<Long> {
 @Override
 public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
  throws JsonParseException {
  try {
   if (json.getAsString().equals("") || json.getAsString().equals("null")) {// long , "" null, 0
     return 0l;
    }
   } catch (Exception ignore) {
  }
  try {
   return json.getAsLong();
  } catch (NumberFormatException e) {
   throw new JsonSyntaxException(e);
  }
 }

 @Override
 public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
  return new JsonPrimitive(src);
 }
}
그래서 사용은 다음과 같다.

return new Retrofit.Builder()
  .client(okHttpClient)// 
  .addConverterFactory(GsonConverterFactory.create(buildGson()))// json 
  .addCallAdapterFactory(RxJavaCallAdapterFactory.create())// Retrofit RxJava
  .baseUrl(baseUrl)
  .build();

/**
 *  "" "null" 
 * 1.int=>0
 * 2.double=>0.00
 * 3.long=>0L
 *
 * @return
 */
public static Gson buildGson() {
 if (gson == null) {
  gson = new GsonBuilder()
    .registerTypeAdapter(Integer.class, new IntegerDefault0Adapter())
    .registerTypeAdapter(int.class, new IntegerDefault0Adapter())
    .registerTypeAdapter(Double.class, new DoubleDefault0Adapter())
    .registerTypeAdapter(double.class, new DoubleDefault0Adapter())
    .registerTypeAdapter(Long.class, new LongDefault0Adapter())
    .registerTypeAdapter(long.class, new LongDefault0Adapter())
    .create();
 }
 return gson;
}
더 이상 백그라운드 json 필드가 비어서 붕괴되지 않을 거예요.
총결산
이상은 이 글의 전체 내용입니다. 본고의 내용이 여러분의 학습이나 업무에 도움이 되기를 바랍니다. 의문이 있으면 댓글로 교류해 주십시오.

좋은 웹페이지 즐겨찾기