开发者社区> 问答> 正文

fastjson 2 复杂的嵌套bean反序列化无法设置默认值

依赖版本

jdk1.8.0_162

com.alibaba fastjson 1.2.28

org.projectlombok lombok 1.16.22

com.alibaba.fastjson2 fastjson2 2.0.4

DTO

@Data @AllArgsConstructor @NoArgsConstructor public class TestDTO {

private String name;
private int age;
private SubDTO subDTO = new SubDTO();

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SubDTO {
    private String id;
    private String nickName;
    private ThiDTO thiDTO = new ThiDTO();
    private FouDTO fouDTO = new FouDTO();
}

}

@Data @AllArgsConstructor @NoArgsConstructor public class ThiDTO { private String h; private String w; }

@Data @AllArgsConstructor @NoArgsConstructor public class FouDTO { private String p; private String t; }

json

{ "name": "123", "age": 3, "subDTO": { "id": "222", "thiDTO": { "h": "444" } } }

运行代码

String s = "{"name":"123","age":3,"subDTO":{"id":"222","thiDTO":{"h":"444"}}}"; TestDTO testDTO2 = JSON.parseObject(s, TestDTO.class, JSONReader.Feature.SupportSmartMatch); TestDTO testDTO1 = com.alibaba.fastjson.JSON.parseObject(s, TestDTO.class); System.out.println("testDTO2 = " + testDTO2); System.out.println("testDTO1 = " + testDTO1);

执行结果

testDTO2 = TestDTO(name=123, age=3, subDTO=TestDTO.SubDTO(id=222, nickName=null, thiDTO=ThiDTO(h=444, w=null), fouDTO=null)) testDTO1 = TestDTO(name=123, age=3, subDTO=TestDTO.SubDTO(id=222, nickName=null, thiDTO=ThiDTO(h=444, w=null), fouDTO=FouDTO(p=null, t=null)))

其中SubDTO是TestDTO的成员内部类,ThiDTO与FouDTO与TestDTO同包类,这种嵌套类结构在使用1.2.x版本可以实现全部成员类的默认值。但是在2版本无法实现fouDTO的默认值。 请问除了将SubDTO从成员内部类提出来外还有别的方式可以实现默认值吗?

原提问者GitHub用户q605450469

展开
收起
大圣东游 2023-04-21 12:03:23 507 0
2 条回答
写回答
取消 提交回答
  • 值得去的地方都没有捷径

    在 fastjson 2 中,可以通过使用 @JSONType 注解来设置默认值。具体来说,您可以在 TestDTO 类上添加 @JSONType 注解,并使用 @JSONType 注解中的 property 属性来设置默认值。例如:

    @JSONType(property = {"subDTO", "thiDTO", "fouDTO"}, orders = {"subDTO", "thiDTO", "fouDTO"}) public class TestDTO { private SubDTO subDTO; private ThiDTO thiDTO; private FouDTO fouDTO; // 省略 getter 和 setter 方法 } java 在上面的代码中,我们在 @JSONType 注解中的 property 属性中设置了 subDTO、thiDTO 和 fouDTO 的默认值,这样在反序列化时,如果 JSON 字符串中没有包含这些属性,fastjson 会自动将它们的值设置为默认值。注意,如果 JSON 字符串中包含这些属性,fastjson 会使用 JSON 字符串中的值覆盖默认值。

    另外,如果您使用的是 @JSONField 注解来设置序列化和反序列化的相关属性,也可以在注解中使用 defaultValue 属性来设置默认值。例如:

    public class FouDTO { @JSONField(defaultValue = "100") private int fouNum; // 省略 getter 和 setter 方法 } java 在上面的代码中,我们在 @JSONField 注解中的 defaultValue 属性中设置了 fouNum 的默认值为 100,这样在反序列化时,如果 JSON 字符串中没有包含 fouNum 属性,fastjson 会自动将它的值设置为 100。

    2023-04-21 21:57:45
    赞同 展开评论 打赏
  • 默认值是有的, 但是构造函数里被覆盖为null, 在fastjson2中有两种解决方法

    1. SubDTO 改为静态内部类

      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      public static class SubDTO2 {
          private String id;
          private String nickName;
          private ThiDTO thiDTO = new ThiDTO();
          private FouDTO fouDTO = new FouDTO();
      }
      
    2. SubDTO去掉@AllArgsConstructor注解

      @Data
      @NoArgsConstructor
      public class SubDTO {
          private String id;
          private String nickName;
          private ThiDTO thiDTO = new ThiDTO();
          private FouDTO fouDTO = new FouDTO();
      }
      

    因为为SubDTO 非静态 内部类时, 创建SubDTO是通过构造是需要传入父TestDTO, 标记@AllArgsConstructor, fastjson2优先使用这个注解创建的构造参数, 那么在JSON文本中没有对应的fouDTO 时, 那么反序列化相当于null, 那么传入构造函数时, SubDTO.fouDTO 本有值的, 缺被覆盖为了null

    原回答者GitHub用户kraity

    2023-04-21 14:50:29
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载