依赖版本
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
在 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。
默认值是有的, 但是构造函数里被覆盖为null, 在fastjson2中有两种解决方法
SubDTO 改为静态内部类
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class SubDTO2 {
private String id;
private String nickName;
private ThiDTO thiDTO = new ThiDTO();
private FouDTO fouDTO = new FouDTO();
}
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
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。