重新创建不带字段 属性 的 DTO class,而不是使用 Gson/Jackson 和 Spring 引导将其设置为空
Recreate DTO class without field property instead of having it null using Gson/Jackson and Spring Boot
我有一个 DTO class returns 这个:
{
"id": "fdbfb1ec-1f1e-4867-9cc8-73929fbcc07e",
"title": "My another category",
"reports": null
}
当我实际上希望我的某些 api 调用不包含报告密钥时,如下所示,而不是将其设置为空。
{
"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":"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 并遇到了同样的问题。
在我想显示的字段上使用 @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;
}
}
这是我和 Jackson 的控制器
@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>
我有一个 DTO class returns 这个:
{
"id": "fdbfb1ec-1f1e-4867-9cc8-73929fbcc07e",
"title": "My another category",
"reports": null
}
当我实际上希望我的某些 api 调用不包含报告密钥时,如下所示,而不是将其设置为空。
{
"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":"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 并遇到了同样的问题。
在我想显示的字段上使用 @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;
}
}
这是我和 Jackson 的控制器
@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>