不幸的是,那里的文档有些误导。
仅当您的类的字段类型与JSON中的字段不匹配时,它才会引发异常,即使这样做,它也会做出一些疯狂的尝试来对其进行修复(例如
int,将JSON中的转换为
String类中的)
)。如果您
Date在POJO中有类似字段的内容,并且
int在JSON中遇到了,则会将其抛出。静默忽略JSON中存在但POJO中不存在的字段,JSON中缺失但POJO中存在的字段设置为
null。
当前,GSON不提供用于任何形式的“严格”反序列化的机制,在该机制中,
@RequiredPOJO中的字段将具有诸如注释的含义。
在您的情况下…我只是将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.}您的另一个选择是编写一个自定义反序列化器,如果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; }}输出:
这是foo这是酒吧这是foo空值线程“ main” com.google.gson.JsonParseException中的异常:JSON中的字段丢失:foo



