Java 使用Gson/Jackson和springboot重新创建没有字段属性的DTO类,而不是使其为null
我有一个DTO类,它返回以下内容:Java 使用Gson/Jackson和springboot重新创建没有字段属性的DTO类,而不是使其为null,java,spring-boot,serialization,jackson,gson,Java,Spring Boot,Serialization,Jackson,Gson,我有一个DTO类,它返回以下内容: { "id": "fdbfb1ec-1f1e-4867-9cc8-73929fbcc07e", "title": "My another category", "reports": null } 当我真的希望我的一些api调用将reports键作为它的一部分时,如下所示,而不是设置为null { "id": "fd
{
"id": "fdbfb1ec-1f1e-4867-9cc8-73929fbcc07e",
"title": "My another category",
"reports": null
}
当我真的希望我的一些api调用将reports键作为它的一部分时,如下所示,而不是设置为null
{
"id": "fdbfb1ec-1f1e-4867-9cc8-73929fbcc07e",
"title": "My another category",
}
我试图使用Gson和Expose注释,相信这会删除我的密钥,但它似乎只是将其改为null。我尝试使用@Expose(serialize=false,deserialize=false)
或不使用注释,因为我的Gson对象使用了excludeFieldsWithoutExposeAnnotation()
片段,但两者都给出了相同的结果。但是,我可以看到我的字符串转换器排除了reports键,并给了我这个{“id”:“fdbfb1ec-1f1e-4867-9cc8-73929fbcc07e”,“title”:“我的另一个类别”}
但不确定在重新创建对象时为什么属性仍然存在,以及此场景的唯一解决方案是否不是通过Gson,而是使用两个完全不同的DTO,一个具有该属性,另一个不具有该属性
@AllArgsConstructor
@NoArgsConstructor
@Data
public class CategoryQueryDto {
@Expose()
private UUID id;
@Expose()
private String title;
@Expose(serialize = false, deserialize = false)
private List<ReportQueryDto> reports;
public CategoryQueryDto(String title) {
this.title = title;
}
public CategoryQueryDto(UUID id, String title) {
this.id = id;
this.title = title;
}
}
@Override
public CategoryQueryDto getCategory(UUID id) {
if (categoryRepository.findById(id).isPresent()) {
Category category = categoryRepository.findById(id).get();
CategoryQueryDto categoryQueryDto = new CategoryQueryDto(category.getId(), category.getTitle());
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String converter = gson.toJson(categoryQueryDto);
categoryQueryDto = gson.fromJson(converter, CategoryQueryDto.class);
return categoryQueryDto;
} else {
return null;
}
}
@allargsconstuctor
@诺尔格构装师
@资料
公共类类别QueryTo{
@暴露()
私有UUID;
@暴露()
私有字符串标题;
@公开(序列化=false,反序列化=false)
私人名单报告;
公共类别QueryTo(字符串标题){
this.title=标题;
}
公共类别QueryTo(UUID id,字符串标题){
this.id=id;
this.title=标题;
}
}
@凌驾
公共类别QueryTo getCategory(UUID id){
if(categoryRepository.findById(id).isPresent()){
Category=categoryRepository.findById(id.get();
CategoryQueryDto CategoryQueryDto=新的CategoryQueryDto(category.getId(),category.getTitle());
Gson Gson=new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
字符串转换器=gson.toJson(categoryQueryDto);
categoryQueryDto=gson.fromJson(转换器,categoryQueryDto.class);
返回类别querydto;
}否则{
返回null;
}
}
多谢各位
更新
这是我在Github上的代码
尝试使用Jackson而不是Gson,但也遇到了同样的问题。在我想显示的字段上使用了@JsonInclude(JsonInclude.Include.NON_NULL)
,但前提是该字段不为NULL且有效
@AllArgsConstructor
@NoArgsConstructor
@Data
public class CategoryQueryDto {
@Expose()
private UUID id;
@Expose()
private String title;
@JsonInclude(JsonInclude.Include.NON_NULL)
private List<ReportQueryDto> reports = null;
public CategoryQueryDto(String title) {
this.title = title;
}
public CategoryQueryDto(UUID id, String title) {
this.id = id;
this.title = title;
}
}
聚甲醛
org.codehaus.jackson
jackson core asl
1.9.13
测试
这听起来很奇怪,特别是因为Gson在默认情况下甚至不应该序列化null
字段(请参阅)。可能是Lombok(您显然正在使用它的注释)以某种方式干扰了Gson吗?删除注释(用于测试)时会发生什么?另外,您的getCategory(…)
方法的目的是什么?看起来它正在序列化,然后立即再次反序列化对象。您好@Marcono1234,谢谢您的评论。我现在试着从我的项目中删除所有的lombok,做普通的构造函数、getter和setter,但恐怕我得到了同样的结果。这是我在Github上的代码,如果您或其他人可以查看一下,并指出我可能做错了什么。我对Spring是个新手,不知道还能尝试什么Gson Gson=new GsonBuilder().excludeFieldswithout exposeannotation().create();字符串转换器=gson.toJson(categoryQueryDto);categoryQueryDto=gson.fromJson(转换器,categoryQueryDto.class)关于你的问题,这是你指的部分吗?是的,这是我尝试使用json,然后通过gson强制返回类对象,看看这是否有效。我不熟悉Spring框架,因此下面的内容可能完全错误,但可能会有所帮助。Spring Boot似乎默认使用Jackson进行JSON序列化。所以你要么要,要么,在这个解决方案中,打开一个关于Gson等价物的问题
@Service
public class CategoryQueryServiceImpl implements CategoryQueryService {
@Autowired
private CategoryRepository categoryRepository;
@Autowired
private ReportRepository reportRepository;
ObjectMapper mapper = new ObjectMapper();
@Override
public CategoryQueryDto getCategory(UUID id) throws JsonProcessingException {
if (categoryRepository.findById(id).isPresent()) {
Category category = categoryRepository.findById(id).get();
CategoryQueryDto categoryQueryDto = new CategoryQueryDto(category.getId(), category.getTitle());
String converter = mapper.writeValueAsString(categoryQueryDto);
categoryQueryDto = mapper.readValue(converter, CategoryQueryDto.class);
return categoryQueryDto;
} else {
return null;
}
}
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
<scope>test</scope>
</dependency>