Gson setara dengan Jackson @JsonInclude (JsonInclude.Include.NON_NULL)

Sep 28 2020

Ini sebenarnya adalah tindak lanjut untuk pertanyaan ini Membuat ulang kelas DTO tanpa properti bidang alih-alih menjadikannya null menggunakan Gson / Jackson dan Spring Boot . Saya awalnya mempostingnya mencoba membuatnya bekerja dengan Gson tetapi hanya dapat melakukannya dengan Jackson menggunakan @JsonInclude(JsonInclude.Include.NON_NULL)tetapi belum dapat menemukan yang setara untuk ini dengan Gson sehingga saya dapat menyimpannya sebagai perpustakaan untuk proyek tersebut.

Mencoba menggunakan @Expose (serialise = false, deserialise = false) di mana saya memiliki anotasi @JsonInclude atau menyetel bidang itu ke null karena Gson secara default akan mengabaikannya, tetapi tampaknya tidak melakukannya.

Akhirnya, saya mencoba menghapus anotasi @Expose sepenuhnya dari untuk melihat apakah Gson akan mengabaikannya tetapi juga tidak berfungsi.

Menempelkannya di sini bagian utama untuk masalah tersebut serta menjaga detail tambahan yang ditambahkan ke postingan asli.

@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;
}

}

Jika ada yang punya ide lain tentang bagaimana melakukan ini, silakan. Terima kasih banyak.

Jawaban

1 anuragsaxena Sep 28 2020 at 16:43

JANGAN membuat serial bidang null (Ini adalah perilaku default serialisasi Gson)

Employee employeeObj = new Employee(1, "John", "Smith", null);
                 
Gson gson = new GsonBuilder()
        .setPrettyPrinting()
        .create(); 
 
System.out.println(gson.toJson(employeeObj));

Keluaran:

{
  "id": 1,
  "firstName": "John",
  "lastName": "Smith"
}

Menyerialkan bidang null (Serialisasi Gson Kustom dengan nilai null disertakan dalam keluaran JSON)

Employee employeeObj = new Employee(1, "John", "Smith", null);
                 
Gson gson = new GsonBuilder()
        .setPrettyPrinting()
        .serializeNulls()
        .create(); 
 
System.out.println(gson.toJson(employeeObj));

Keluaran:

{
  "id": 1,
  "firstName": "John",
  "lastName": "Smith",
  "emailId": null
}
FrancislainyCampos Sep 29 2020 at 03:27

Tampaknya perilaku default untuk Gson tidak terjadi karena Spring Boot menggunakan Jackson sebagai pustaka serialisasi default. Menimpa ini dengan menempelkan baris di bawah ini dalam application.propertiesfile telah memperbaiki masalah saya.

spring.mvc.converters.preferred-json-mapper=gson