Java 如果JsonStr中缺少任何键/值,如何在从JsonStr转换为PojoClassObj时引发异常?

Java 如果JsonStr中缺少任何键/值,如何在从JsonStr转换为PojoClassObj时引发异常?,java,json,gson,pojo,Java,Json,Gson,Pojo,我尝试使用@NotNull注释,但没有成功。如果JsonString中缺少任何字段,则会给出null(字符串)或zero(int)。但是我想要的是,如果类中定义的JsonStr中缺少任何字段,则应该抛出异常 添加:MyPojoClass可能有对象引用或多级对象引用。我使用Gson将字符串转换为obj。 为了进一步澄清,我在下面添加了我的代码: JsonStr: { "name":"John", "id":1, "roll":100, "c":{ "city":

我尝试使用
@NotNull
注释,但没有成功。如果
JsonString
中缺少任何字段,则会给出
null(字符串)
zero(int)
。但是我想要的是,如果类中定义的
JsonStr
中缺少任何字段,则应该抛出异常

添加:My
PojoClass
可能有对象引用或多级对象引用。我使用Gson
字符串
转换为obj。 为了进一步澄清,我在下面添加了我的代码:

JsonStr:

{
   "name":"John",
   "id":1,
   "roll":100,
   "c":{
      "city":"Dhaka",
      "school":"B. govt. School"
   }
}
代码:

public class C {

    private String city;
    private String school;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }

}
public class B {

    private String name;
    private int id;
    @NotNull
    private int roll;
    private C c;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public int getRoll() {
        return roll;
    }

    public void setRoll(int roll) {
        this.roll = roll;
    }

    public C getC() {
        return c;
    }

    public void setC(C c) {
        this.c = c;
    }

}
try {
                B obj = new B();
                String str = "{\"name\":\"John\",\"id\":1,\"c\":{\"city\":\"dhaka\",\"school\":\"school\"}}";
                obj = gson.fromJson(str, B.class);

            } catch (RuntimeException e) {
                 System.out.println("exception Message");

            }
ClassB:

public class C {

    private String city;
    private String school;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }

}
public class B {

    private String name;
    private int id;
    @NotNull
    private int roll;
    private C c;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public int getRoll() {
        return roll;
    }

    public void setRoll(int roll) {
        this.roll = roll;
    }

    public C getC() {
        return c;
    }

    public void setC(C c) {
        this.c = c;
    }

}
try {
                B obj = new B();
                String str = "{\"name\":\"John\",\"id\":1,\"c\":{\"city\":\"dhaka\",\"school\":\"school\"}}";
                obj = gson.fromJson(str, B.class);

            } catch (RuntimeException e) {
                 System.out.println("exception Message");

            }
main类:

public class C {

    private String city;
    private String school;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }

}
public class B {

    private String name;
    private int id;
    @NotNull
    private int roll;
    private C c;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public int getRoll() {
        return roll;
    }

    public void setRoll(int roll) {
        this.roll = roll;
    }

    public C getC() {
        return c;
    }

    public void setC(C c) {
        this.c = c;
    }

}
try {
                B obj = new B();
                String str = "{\"name\":\"John\",\"id\":1,\"c\":{\"city\":\"dhaka\",\"school\":\"school\"}}";
                obj = gson.fromJson(str, B.class);

            } catch (RuntimeException e) {
                 System.out.println("exception Message");

            }
对于字段roll,如果
JsonStr
中不存在该字段,我使用
@NotNull
抛出异常,但它给出0值而不抛出任何异常

我如何实现这一点

请不要说这是重复的,因为我已经看到了这些问题:


您是否尝试过使用包装类而不是原语

使用以下命令:

@NotNull
私有整数滚动;

@NotNull
不是Gson的一部分,默认情况下它无法处理它(除非您自己添加支持)。此外,可空性检查注释不应应用于原语字段——一般来说,这没有多大意义。此外,默认的
int
字段值为
0
,并且Gson不会检查特定字段是否从JSON文档中读取。但是,如果您:

  • 通过将原语
    int
    更改为其可为空的包装器
    Integer
    ,稍微更改映射
  • 实现自定义后处理验证类型适配器
比如说,

final class Person{
最终字符串名称=null;
final int id=Integer.valueOf(0);//final原语字段由javac内联
@NotNull
最终整数滚动=空;
@序列化名称(“c”)
最终位置=空;
}
最终类位置{
最终字符串city=null;
最终字符串school=null;
}
下一步就是创建自己的类型适配器来检查可为空的字段

final类NotNullTypeAdapterFactory
实现TypeAdapterFactory{
//类型适配器工厂不持有任何状态,因此不需要多次实例化它
私有静态最终类型适配器工厂notNullTypeAdapterFactory=新notNullTypeAdapterFactory();
私有NotNullTypeAdapterFactory(){
}
静态TypeAdapterFactory getNotNullTypeAdapterFactory(){
返回notNullTypeAdapterFactory;
}
@凌驾
公共类型适配器创建(最终Gson Gson、最终TypeToken TypeToken){
最终集合notNullFields=getNotNullFields(typeToken.getRawType());
//如果没有找到@NotNull字段,那么只需告诉Gson选择下一个最好的类型适配器
if(notNullFields.isEmpty()){
返回null;
}
//如果至少有一个@NotNull字段,则获取原始类型适配器
final-TypeAdapter-delegateTypeAdapter=gson.getDelegateAdapter(这个,typeToken);
返回新的TypeAdapter(){
@凌驾
公共无效写入(最终JsonWriter out,最终T值)
抛出IOException{
delegateTypeAdapter.write(out,value);
}
@凌驾
公共T读(最终JsonReader in)
抛出IOException{
试一试{
//读取值。。。
最终T值=delegateTypeAdapter.read(in);
//…并进行一些后处理
对于(最终字段f:notNullFields){
如果(f.get(value)==null){
抛出新的MalformedJsonException(f+“没有值”);
}
}
返回值;
}捕获(最终非法访问例外){
抛出新的IOException(ex);
}
}
};
}
私有静态集合getNotNullFields(最终类clazz){
//基元类型和java.lang.Object没有@NotNull
if(clazz.isPrimitive()| | clazz==Object.class){
返回空列表();
}
//扫描从底部子类到顶部超类的整个层次结构(上面提到的java.lang.Object除外)
最终集合notNullFields=new ArrayList();
for(Class c=clazz;c!=Object.Class;c=c.getSuperclass()){
for(最终字段f:c.getDeclaredFields()){
if(f.isAnnotationPresent(NotNull.class)){
//别忘了让私有字段可以访问
f、 setAccessible(true);
添加(f);
}
}
}
返回非空字段;
}
}
测试(使用一些Google Guava和自定义资源阅读器):

private static final Gson Gson=new GsonBuilder()
.registerTypeAdapterFactory(getNotNullTypeAdapterFactory())
.create();
公共静态void main(最终字符串…参数)
抛出IOException{
for(最后一个字符串resourceName:ImmutableList.of(“包含roll.json的文件”、“不包含roll.json的文件”)){
System.out.println(“反序列化”+resourceName);
try(最终JsonReader JsonReader=getPackageResourceJsonReader(Q44362030.class,resourceName)){
试一试{
final Person=gson.fromJson(jsonReader,Person.class);
System.out.println(person.name+“”+person.roll);
}捕获(最终异常){
System.out.println(“FAI