2016-07-19 4 views
2

で指定したフィールドが含まれていない場合に失敗するPOJOにGsonデシリアライズを取得します。POJOには、次のJSONファイルを考えるとJSON

{ 
    "validField":"I'm here", 
    "invalidField":"I'm not here :-(", 
} 

そして

public class Pojo { 
    public String validField; 
} 

私はにJSONをデシリアライズするためにgsonを使用してPOJO私はそれがPojoに存在しないのでinvalidFieldで失敗することを望みます。

// This should fail but just ignores 'invalidField' property 
Pojo pojo = new Gson().fromJson(json, Pojo.class); 

どのように起こるようにするためのアイデアですか?

答えて

0

代替手段の欠如私は以下のことを考え出しました。私はまだサポートされている解決策があるかどうか聞いてみたい。

private static void validateAllDataLoaded(JsonElement element, Object returnType, String entryName) throws IOException { 

    if (element.isJsonNull()) { 
     return; 
    } 

    if (element.isJsonArray()) { 
     checkFieldExists(entryName, returnType); 

     for (Object arrayItem : (ArrayList<?>) returnType) { 
      for (JsonElement item : element.getAsJsonArray()) { 
       validateAllDataLoaded(item, arrayItem, entryName); 
      } 
     } 
    } 

    if (element.isJsonObject()) { 
     checkFieldExists(entryName, returnType); 

     for (Map.Entry<String, JsonElement> entry : element.getAsJsonObject().entrySet()) { 
      if (!entry.getValue().isJsonNull() && !entry.getValue().isJsonPrimitive()) { 
       validateAllDataLoaded(entry.getValue(), getField(entry.getKey(), returnType), ""); 
      } else { 
       validateAllDataLoaded(entry.getValue(), returnType, entry.getKey()); 
      } 
     } 
    } 

    if (element.isJsonPrimitive()) { 
     checkFieldExists(entryName, returnType); 
    } 
} 

private static void checkFieldExists(String entryName, Object returnType) throws IOException { 
    if (entryName.isEmpty()) { 
     return; 
    } 

    Field[] fields = returnType.getClass().getDeclaredFields(); 
    boolean exists = Arrays.asList(fields).stream().filter(f -> f.getName().equals(entryName)).count() == 1; 

    if (!exists) { 
     throw new IOException("JSON element '" + entryName + "' is not a field in the destination class " + returnType.getClass().getName()); 
    } 
} 

private static Object getField(String entryName, Object returnType) throws IOException { 
    if (entryName.isEmpty()) { 
     return null; 
    } 

    Field field; 
    try { 
     field = returnType.getClass().getDeclaredField(entryName); 
     field.setAccessible(true); 

     return field.get(returnType); 
    } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { 
     throw new IOException(e); 
    } 
} 
関連する問題