残念ながら、ドキュメントは少し誤解を招く可能性があります。
クラスにJSONの型と一致しない型のフィールドがある場合にのみ例外がスローされ、それでもそれを修正するためにいくつかのクレイジーなことを行います(たとえばint
、JSONの aをクラスの a に変換します) String
)。Date
POJO にフィールドのようなものがint
あり、JSON で に遭遇した場合、それをスローします。JSON に存在するが POJO に存在しないフィールドは無視され、JSON に存在しないが POJO に存在するフィールドは に設定されnull
ます。
@Required
現在、GSON は、POJO 内のフィールドの注釈の ようなものを持つ、あらゆる種類の「厳密な」デシリアライゼーションのメカニズムを提供していません。
あなたの場合... POJOを展開して内部エラーオブジェクトを含めるだけです...次のようなものです:
class Dummy {
private String foo;
private int bar;
private Error error;
private class Error {
String publicMsg;
String msg;
}
public boolean isError() {
return error != null;
}
// setters and getters for your data, the error msg, etc.
}
もう 1 つのオプションは、JSON が次のようなエラーである場合に例外をスローするカスタム デシリアライザーを作成することです。
class MyDeserializer implements JsonDeserializer<Dummy>
{
@Override
public Dummy deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException
{
JsonObject jsonObject = (JsonObject) json;
if (jsonObject.get("error") != null)
{
throw new JsonParseException("Error!");
}
return new Gson().fromJson(json, Dummy.class);
}
}
追加する編集:誰かが最近これに賛成票を投じて再読したところ、「ほら、これは自分でできるし、便利かもしれない」と思いました。
これは、OPが望んでいたことを正確に行う再利用可能なデシリアライザーと注釈です。制限は、POJO がカスタム デシリアライザーをそのまま必要とする場合、もう少し先に進みGson
、コンストラクターでオブジェクトを渡してオブジェクト自体にデシリアライズするか、チェックアウトするアノテーションを別のメソッドに移動して使用する必要があることです。それをデシリアライザーに入れます。独自の例外を作成してに渡すことで、例外処理を改善して、呼び出し元JsonParseException
で検出できるようにすることもできます。getCause()
とはいえ、ほとんどの場合、これは機能します。
public class App
{
public static void main(String[] args)
{
Gson gson =
new GsonBuilder()
.registerTypeAdapter(TestAnnotationBean.class, new AnnotatedDeserializer<TestAnnotationBean>())
.create();
String json = "{\"foo\":\"This is foo\",\"bar\":\"this is bar\"}";
TestAnnotationBean tab = gson.fromJson(json, TestAnnotationBean.class);
System.out.println(tab.foo);
System.out.println(tab.bar);
json = "{\"foo\":\"This is foo\"}";
tab = gson.fromJson(json, TestAnnotationBean.class);
System.out.println(tab.foo);
System.out.println(tab.bar);
json = "{\"bar\":\"This is bar\"}";
tab = gson.fromJson(json, TestAnnotationBean.class);
System.out.println(tab.foo);
System.out.println(tab.bar);
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface JsonRequired
{
}
class TestAnnotationBean
{
@JsonRequired public String foo;
public String bar;
}
class AnnotatedDeserializer<T> implements JsonDeserializer<T>
{
public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException
{
T pojo = new Gson().fromJson(je, type);
Field[] fields = pojo.getClass().getDeclaredFields();
for (Field f : fields)
{
if (f.getAnnotation(JsonRequired.class) != null)
{
try
{
f.setAccessible(true);
if (f.get(pojo) == null)
{
throw new JsonParseException("Missing field in JSON: " + f.getName());
}
}
catch (IllegalArgumentException ex)
{
Logger.getLogger(AnnotatedDeserializer.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(AnnotatedDeserializer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
return pojo;
}
}
出力:
ふーです
これはバーです
ふーです
ヌル
スレッド「メイン」com.google.gson.JsonParseException の例外: JSON にフィールドがありません: foo