Gson эквивалентен Джексону @JsonInclude(JsonInclude.Include.NON_NULL)

На самом деле это ответ на этот вопрос gson-j?noredirect=1#comment113310166_64006127">Восстановите класс DTO без свойства поля вместо того, чтобы сделать его нулевым, используя Gson/Jackson и Spring Boot. Первоначально я опубликовал его, пытаясь заставить его работать с Gson, но смог сделать это только с Джексоном, используя @JsonInclude(JsonInclude.Include.NON_NULL), но не смог найти эквивалент для этого с Gson, поэтому я могу сохранить это как библиотеку для проекта.

Пробовал использовать @Expose(serialise=false, deserialise=false), где у меня была аннотация @JsonInclude или установить для этого поля значение null, поскольку думал, что Gson по умолчанию игнорирует это, но, похоже, он этого не делает.

Наконец, я попытался полностью удалить аннотацию @Expose, чтобы посмотреть, будет ли 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());

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

}

Если у кого-то есть другие идеи о том, как это сделать, пожалуйста. Большое спасибо.


person Francislainy Campos    schedule 28.09.2020    source источник


Ответы (2)


НЕ сериализуйте пустые поля (это поведение сериализации Gson по умолчанию)

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

Выход:

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

Сериализация нулевых полей (пользовательская сериализация Gson с нулевыми значениями, включенными в вывод JSON)

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

Выход:

{
  "id": 1,
  "firstName": "John",
  "lastName": "Smith",
  "emailId": null
}
person anurag saxena    schedule 28.09.2020
comment
Привет, спасибо за ответ. Проголосовать за это как полезное, чтобы выяснить, в чем проблема, поскольку поведение по умолчанию для Gson не имело места, и его пришлось переопределить в файле .properties. - person Francislainy Campos; 29.09.2020

Кажется, что поведение по умолчанию для Gson не имело места, поскольку Spring Boot использует Jackson в качестве библиотеки сериализации по умолчанию. Перезапись этого путем вставки строки ниже в файл application.properties устранила проблему для меня.

spring.mvc.converters.preferred-json-mapper=gson
person Francislainy Campos    schedule 29.09.2020