Avatar ·

Как заставить Jackson игнорировать null поля при сериализации в JSON?

Всем привет! Я только начинаю осваивать Jackson для работы с JSON в Java, и столкнулся с проблемой. У меня есть класс User с несколькими полями, некоторые из которых могут быть null. Когда я сериализую объект в JSON, Jackson по умолчанию включает эти null поля, что засоряет вывод. Например:

public class User {
    private String name;
    private String email;
    private String phone;
    // геттеры и сеттеры
}

User user = new User();
user.setName("Иван");
// email и phone не заданы, они null

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
// Результат: {"name":"Иван","email":null,"phone":null}

Мне нужно, чтобы поля с null значениями просто не включались в JSON. Я хочу получить что-то вроде: {"name":"Иван"}. Подскажите, как это сделать? Я слышал про аннотации, но не знаю, какую именно использовать. Заранее спасибо!

<<>>

Как решить проблему: игнорирование null полей при сериализации Jackson

Есть несколько способов заставить Jackson игнорировать null поля. Я покажу самые популярные и надёжные.

Способ 1: Глобальная настройка ObjectMapper (рекомендуется)

Самый простой способ — настроить ObjectMapper один раз, и все последующие сериализации будут игнорировать null поля:

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

User user = new User();
user.setName("Иван");
// email и phone null

String json = mapper.writeValueAsString(user);
// Результат: {"name":"Иван"}

Это работает для всех объектов, которые вы сериализуете через этот mapper. Если вы используете Spring Boot, можно настроить это в application.properties:

spring.jackson.serialization-inclusion=non_null

Способ 2: Аннотация на уровне класса

Если вы хотите управлять этим для конкретного класса, используйте аннотацию @JsonInclude:

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
    private String name;
    private String email;
    private String phone;
    // геттеры и сеттеры
}

Теперь при сериализации любого экземпляра User null поля будут автоматически исключены.

Способ 3: Аннотация на уровне поля

Можно указать для конкретного поля, что его нужно игнорировать, если оно null:

public class User {
    private String name;
    
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String email;
    
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String phone;
}

Это полезно, если у вас есть поля, которые должны всегда отображаться (например, обязательные), и поля, которые можно опустить.

Дополнительные опции для JsonInclude.Include

  • ALWAYS — всегда включать поле (по умолчанию)
  • NON_NULL — не включать, если значение null
  • NON_ABSENT — не включать для null и Optional.empty()
  • NON_EMPTY — не включать null и пустые коллекции/строки
  • NON_DEFAULT — не включать, если значение равно значению по умолчанию для типа

Важно: Убедитесь, что у вас правильная версия Jackson. Все описанные способы работают с Jackson 2.x (начиная с 2.0). Если используете старую версию (1.x), синтаксис может отличаться.

Пример полного решения

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) throws Exception {
        // Вариант 1: через ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        
        // Вариант 2: через аннотацию (раскомментировать в классе User)
        
        User user = new User();
        user.setName("Анна");
        // email не задан, phone тоже
        
        String json = mapper.writeValueAsString(user);
        System.out.println(json); // {"name":"Анна"}
    }
}

@JsonInclude(JsonInclude.Include.NON_NULL)
class User {
    private String name;
    private String email;
    private String phone;
    // геттеры и сеттеры...
}

Выбирайте способ, который лучше подходит для вашего проекта. Для больших проектов обычно используют глобальную настройку в ObjectMapper, а для отдельных классов — аннотации.

<<>>

Альтернативный подход: использование фильтров и @JsonIgnore

Если вам нужно более тонкое управление сериализацией, можно использовать комбинацию @JsonIgnore и собственных фильтров. Однако это менее удобно для массового игнорирования null полей.

Использование @JsonIgnore для конкретных полей

public class User {
    private String name;
    
    @JsonIgnore
    private String email; // всегда игнорируется
    
    private String phone;
}

Но это не решает проблему динамического игнорирования null — поле будет исключено всегда, даже если оно не null.

Использование @JsonProperty(required = false)

Эта аннотация не влияет на сериализацию напрямую, но может быть полезна в связке с другими настройками:

public class User {
    private String name;
    
    @JsonProperty(required = false)
    private String email;
}

Итог: Для вашей задачи лучше всего подходит @JsonInclude(Include.NON_NULL) или глобальная настройка ObjectMapper. Альтернативы менее гибкие или решают другую проблему.

Если вы используете Spring Boot, рекомендую настроить свойство spring.jackson.serialization-inclusion=non_null — это самый простой и поддерживаемый способ.