Gson tương đương với Jackson @JsonInclude (JsonInclude.Include.NON_NULL)
Đây thực sự là một phần tiếp theo cho câu hỏi này Tạo lại lớp DTO không có thuộc tính trường thay vì để nó rỗng bằng cách sử dụng Gson / Jackson và Spring Boot . Ban đầu tôi đã đăng nó để cố gắng làm cho nó hoạt động với Gson nhưng chỉ có thể làm điều đó với Jackson bằng cách sử dụng @JsonInclude(JsonInclude.Include.NON_NULL)nhưng không thể tìm thấy thứ tương đương cho điều này với Gson nên tôi có thể giữ nó làm thư viện cho dự án.
Đã thử sử dụng @Expose (serialise = false, deserialise = false) trong đó tôi có chú thích @JsonInclude hoặc đặt trường đó thành null vì nghĩ rằng Gson theo mặc định sẽ bỏ qua điều đó, nhưng có vẻ như không làm vậy.
Cuối cùng, tôi đã cố gắng xóa hoàn toàn chú thích @Expose để xem liệu Gson có bỏ qua điều đó nhưng cũng không hoạt động hay không.
Dán nó ở đây các phần chính của vấn đề cũng như giữ các chi tiết bổ sung được thêm vào bài đăng gốc.
@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());
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String converter = gson.toJson(categoryQueryDto);
categoryQueryDto = gson.fromJson(converter, CategoryQueryDto.class);
// Jackson
//String converter = mapper.writeValueAsString(categoryQueryDto);
//categoryQueryDto = mapper.readValue(converter, CategoryQueryDto.class);
return categoryQueryDto;
} else {
return null;
}
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class CategoryQueryDto {
@Expose()
private UUID id;
@Expose()
private String title;
// Jackson
// @JsonInclude(JsonInclude.Include.NON_NULL)
private List<ReportQueryDto> reports = null;
public CategoryQueryDto(UUID id, String title) {
this.id = id;
this.title = title;
}
}
Nếu ai có bất kỳ ý tưởng nào khác về cách làm điều này, xin vui lòng. Cảm ơn rât nhiều.
Trả lời
KHÔNG tuần tự hóa các trường rỗng (Đây là hành vi mặc định của tuần tự hóa Gson)
Employee employeeObj = new Employee(1, "John", "Smith", null);
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
System.out.println(gson.toJson(employeeObj));
Đầu ra:
{
"id": 1,
"firstName": "John",
"lastName": "Smith"
}
Tuần tự hóa các trường rỗng (Tuần tự hóa Gson tùy chỉnh với các giá trị null được bao gồm trong đầu ra JSON)
Employee employeeObj = new Employee(1, "John", "Smith", null);
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.serializeNulls()
.create();
System.out.println(gson.toJson(employeeObj));
Đầu ra:
{
"id": 1,
"firstName": "John",
"lastName": "Smith",
"emailId": null
}
Có vẻ như hành vi mặc định cho Gson đã không diễn ra vì Spring Boot sử dụng Jackson làm thư viện tuần tự hóa mặc định. Việc ghi đè điều này bằng cách dán dòng bên dưới trong application.propertiestệp đã khắc phục sự cố cho tôi.
spring.mvc.converters.preferred-json-mapper=gson