Сериализация Джексона: Игнорировать пустые значения (или null)


в настоящее время я использую jackson 2.1.4, и у меня возникли некоторые проблемы с игнорированием полей при преобразовании объекта в строку JSON.

вот мой класс, который действует как объект для преобразования:

public class JsonOperation {

public static class Request {
    @JsonInclude(Include.NON_EMPTY)
    String requestType;
    Data data = new Data();

    public static class Data {
    @JsonInclude(Include.NON_EMPTY)
        String username;
        String email;
        String password;
        String birthday;
        String coinsPackage;
        String coins;
        String transactionId;
        boolean isLoggedIn;
    }
}

public static class Response {
    @JsonInclude(Include.NON_EMPTY)
    String requestType = null;
    Data data = new Data();

    public static class Data {
        @JsonInclude(Include.NON_EMPTY)
        enum ErrorCode { ERROR_INVALID_LOGIN, ERROR_USERNAME_ALREADY_TAKEN, ERROR_EMAIL_ALREADY_TAKEN };
        enum Status { ok, error };

        Status status;
        ErrorCode errorCode;
        String expiry;
        int coins;
        String email;
        String birthday;
        String pictureUrl;
        ArrayList <Performer> performer;
    }
}
}

и вот как я его конвертирую:

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

JsonOperation subscribe = new JsonOperation();

subscribe.request.requestType = "login";

subscribe.request.data.username = "Vincent";
subscribe.request.data.password = "test";


Writer strWriter = new StringWriter();
try {
    mapper.writeValue(strWriter, subscribe.request);
} catch (JsonGenerationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (JsonMappingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Log.d("JSON", strWriter.toString())

вот вывод:

{"data":{"birthday":null,"coins":null,"coinsPackage":null,"email":null,"username":"Vincent","password":"test","transactionId":null,"isLoggedIn":false},"requestType":"login"}

как я могу избежать этих нулевых значений? Я только хочу взять необходимую информацию для" подписки " цели!

вот именно выход, который Я ищу:

{"data":{"username":"Vincent","password":"test"},"requestType":"login"}

Я также попробовал @JsonInclude (Include.NON_NULL) и поставил все мои переменные в null, но это тоже не сработало! Спасибо за вашу помощь ребята!

8 108

8 ответов:

у вас есть аннотация в неправильном месте - она должна быть в классе, а не в поле. я.е:

@JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case 
public static class Request {
  // ...
}

как отмечено в комментариях, в версии 2.х+ синтаксис аннотация:

@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // or JsonSerialize.Inclusion.NON_EMPTY

другой вариант-настроить ObjectMapper напрямую, просто позвонив по телефону mapper.setSerializationInclusion(Include.NON_NULL);

(для справки, я думаю, что популярность этого ответа является признаком того, что эта аннотация должны применяется на основе поля за полем *кхм @fasterxml*)

вы также можете установить глобальный параметр:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

также вы можете попробовать использовать

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

Если вы имеете дело с Джексоном с версией ниже 2+ (1.9.5) я протестировал его, вы можете легко использовать эту аннотацию над классом. Не для указанных атрибутов, только на декларацию класса.

вам нужно добавить импорт com.быстрее!Джексон.аннотация.JsonInclude;

добавить

@JsonInclude(JsonInclude.Include.NON_NULL)

поверх POJO

Если у вас есть вложенные POJO, то

@JsonInclude(JsonInclude.Include.NON_NULL)

нужно добавить на каждый значений.

Примечание.: JAXRS (Джерси ) автоматически обрабатывает этот сценарий 2.6 и выше.

для Джексона 2.x

@JsonInclude (JsonInclude.Включать.NON_NULL) непосредственно перед полем.

недавно у меня была аналогичная проблема с версией 2.6.6.

@JsonInclude(JsonInclude.Include.NON_NULL)

использование аннотации выше либо на уровне файла, либо на уровне класса не работает должным образом. POJO был изменчив там, где я применял аннотацию. Когда я изменил поведение POJO, чтобы быть неизменным, аннотация сработала волшебно.

Я не уверен, что его до новой версии или предыдущих версий этой библиотеки было подобное поведение, но для 2.6.6, конечно, вам нужно иметь неизменяемый POJO для аннотации, чтобы работать.

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

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

поэтому, если вы хотите, чтобы все нулевые поля игнорировались при сериализации JSON, используйте аннотацию на уровне класса, но если вы хотите, чтобы только несколько полей игнорировались в классе, используйте его над этими конкретными полями. Таким образом, его более читаемым & легко для поддержания, если вы хотите изменить поведение для конкретного ответа.

или вы можете использовать GSON [https://code.google.com/p/google-gson/], где эти пустые поля будут автоматически удалены.

SampleDTO.java

public class SampleDTO {

    String username;
    String email;
    String password;
    String birthday;
    String coinsPackage;
    String coins;
    String transactionId;
    boolean isLoggedIn;

    // getters/setters
}

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

@JsonInclude(JsonInclude.Include.NON_ABSENT)