使用 Gson/Jackson 和 Spring Boot 重新创建没有字段属性的 DTO 类,而不是使其为空
Posted
技术标签:
【中文标题】使用 Gson/Jackson 和 Spring Boot 重新创建没有字段属性的 DTO 类,而不是使其为空【英文标题】:Recreate DTO class without field property instead of having it null using Gson/Jackson and Spring Boot 【发布时间】:2021-01-08 08:47:36 【问题描述】:我有一个返回这个的 DTO 类:
"id": "fdbfb1ec-1f1e-4867-9cc8-73929fbcc07e",
"title": "My another category",
"reports": null
当我实际上希望我的一些 api 调用按照下面的方法将报告键作为它的一部分而不是设置为 null 时。
"id": "fdbfb1ec-1f1e-4867-9cc8-73929fbcc07e",
"title": "My another category",
我尝试使用 Gson 和 Expose 注释,相信这会删除我的密钥,但它似乎只是将其变为 null。我尝试使用 @Expose(serialize = false, deserialize = false)
或不使用注释,因为我的 Gson 对象使用 excludeFieldsWithoutExposeAnnotation()
片段,但两者都给了我相同的结果。但是,我可以看到我的字符串转换器排除了报告键并给了我这个"id":"fdbfb1ec-1f1e-4867-9cc8-73929fbcc07e","title":"My another category"
但不确定为什么在重新创建对象时该属性仍然存在,以及这种情况的唯一解决方案是否不是通过 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;
非常感谢。
更新
这是我在 Github 上的代码https://github.com/francislainy/gatling_tool_backend
尝试使用 Jackson 而不是 Gson,但遇到了同样的问题。
【问题讨论】:
这听起来很奇怪,尤其是因为 Gson 默认情况下甚至不应该序列化null
字段(请参阅 GsonBuilder.serializeNulls()
)。会不会是 Lombok(您显然正在使用其注释)以某种方式干扰 Gson?当您删除注释(用于测试)时会发生什么?还有你的getCategory(...)
方法的目的是什么?看起来它正在序列化,然后立即再次反序列化对象。
嗨@Marcono1234,感谢您的评论。我现在尝试从我的项目中删除所有 lombok 并执行普通的构造函数、getter 和 setter,但恐怕我得到了相同的结果。这是我在 Github 上的代码,如果您或其他人可以查看并指出我可能做错了什么。我是 Spring 的新手,不太确定还能尝试什么。 github.com/francislainy/gatling_tool_backend
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); String converter = gson.toJson(categoryQueryDto); categoryQueryDto = gson.fromJson(converter, CategoryQueryDto.class);
关于你的问题,这是你指的部分吗?是的,那是我尝试 json 然后强行通过 gson 回到类对象,看看这是否可行。
我不熟悉 Spring 框架,所以下面的内容可能完全错误,但也许它仍然有帮助。看来 Spring Boot 默认使用 Jackson 进行 JSON 序列化。所以你要么必须configure Jackson要么specify that Gson is used。
【参考方案1】:
在我想显示的字段上使用@JsonInclude(JsonInclude.Include.NON_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;
这里是我和杰克逊的控制器
@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;
POM
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
<scope>test</scope>
</dependency>
【讨论】:
在此解决方案的 Gson 等效问题***.com/questions/64105969/…以上是关于使用 Gson/Jackson 和 Spring Boot 重新创建没有字段属性的 DTO 类,而不是使其为空的主要内容,如果未能解决你的问题,请参考以下文章
Spring boot与Jackson ObjectMapper
Json 工具介绍 fastjson gson jackson