Jackson serileştirmesi: boş değerleri yoksay (veya null)


138

Şu anda jackson 2.1.4 kullanıyorum ve bir nesneyi JSON dizesine dönüştürürken alanları görmezden gelmekte sorun yaşıyorum.

İşte dönüştürülecek nesne olarak benim sınıf:

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

Ve işte nasıl dönüştürdüğümü:

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())

İşte çıktı:

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

Bu boş değerlerden nasıl kaçınabilirim? Sadece "abonelik" amacı için gerekli bilgileri almak istiyorum!

İşte tam olarak aradığım çıktı:

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

Ayrıca @JsonInclude (Include.NON_NULL) denedim ve tüm değişkenleri null koymak, ama o da işe yaramadı! Yardımlarınız için teşekkürler çocuklar!


Yanıtlar:


247

Ek açıklama yanlış yerde var - alan üzerinde değil sınıfta olması gerekiyor. yani:

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

Yorumlarda belirtildiği gibi, 2.x'in altındaki sürümlerde bu ek açıklama için sözdizimi:

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

Diğer seçenek, ObjectMapperdoğrudan arayarak doğrudan yapılandırmaktır.mapper.setSerializationInclusion(Include.NON_NULL);

(kayıt için, bu cevabın popülaritesinin bu ek açıklamanın alan bazında geçerli olması gerektiğinin bir göstergesi olduğunu düşünüyorum , @fasterxml)


İnclude.NON_NULL ek açıklamasını çalıştırmanın gerçekten bir yolu yok mu? Yoksa NON_EMTPY olanı? Çünkü hangisinin null olacağını biliyorum, ama duruma bağlı. Serileştirmek / serileştirmek istediğiniz her nesne için aynı "JsonOperation" sınıfını kullanıyorum ve yalnızca duruma bağlı olarak kullanmam gereken değişkenleri başlatıyorum. Bunu yapmak için iyi bir yol mu yoksa sadece ihtiyacım olan değişkenleri içeren birkaç sınıf yapmalıyım (asla boş / boş bir değişken olmayacağından hiçbir ek açıklama kullanmam
gerekmeyecek

26
Sözdizimi en son sürümde @JsonSerialize (include = JsonSerialize.Inclusion.NON_NULL) ve @JsonSerialize (include = JsonSerialize.Inclusion.NON_EMPTY olarak değiştirildi) .Inclusion.NON_DEFAULT)
Maciej

1
Dersten önce veya çalıştığı mülkten önce @JsonSerialize (include = Inclusion.NON_NULL) kullanın ...
kuğu

1
@ drewmoore lütfen tekrar kontrol edin, @JsonInclude(JsonSerialize.Inclusion.NON_NULL) olmalı @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)ve ayrıca eski kullanımdan kaldırılmış yol. bu yüzden "2.x altındaki sürüm"
yazmalısınız,

2
2. + kullanım@JsonInclude(Include.NON_NULL)
Honghe.Wu

48

Global seçeneği de ayarlayabilirsiniz:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

15

Ayrıca kullanmayı deneyebilirsiniz

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

Eğer test 2 + (1.9.5) altında sürümü ile jackson ile ilgileniyorsanız, kolayca bu ek açıklama sınıfın üzerinde kullanabilirsiniz. Nitelikler için değil, yalnızca sınıf bildirimi için belirtilmez.


2
include özelliği JsonSerialize JsonInclude lehine kullanımdan kaldırılmıştır
fd8s0

2
dediğim gibi: jackson ile birlikte sürüm 2+ (1.9.5)
erhanasikoglu

soru belirli bir sürüm hakkında soruyor 2.1.4
fd8s0

14

Eklemelisin import com.fasterxml.jackson.annotation.JsonInclude;

Ekle

@JsonInclude(JsonInclude.Include.NON_NULL)

POJO'nun üstünde

POJO'yu iç içe yerleştirdiyseniz,

@JsonInclude(JsonInclude.Include.NON_NULL)

her değeri eklemeniz gerekir.

NOT: JAXRS (Jersey) bu senaryo 2.6 ve üzerini otomatik olarak ele alır.


org.codehaus.jackson.annotate paketini kullanırken benzer bir işlevsellik var mı?
pkran

Evet, getter yönteminin üstüne private int id örneği ekleyebilirsiniz; @JsonIgnore public int getId () {dönüş kimliği; }
vaquar khan

1
Mevcut cevaplarla aynı
Karl Richter

4

Jackson 2.x için

@JsonInclude(JsonInclude.Include.NON_NULL)

tarladan hemen önce.


2
Mevcut cevaplarla aynı
Karl Richter

2

2.6.6 sürümünde benzer bir sorun yaşıyordum

@JsonInclude(JsonInclude.Include.NON_NULL)

Dosyalama veya sınıf düzeyinde yukarıdaki ek açıklamayı kullanmak beklendiği gibi çalışmıyor. POJO, açıklamayı uyguladığım yerde değiştirilebilirdi. POJO'nun davranışını değişmez olarak değiştirdiğimde, ek açıklama sihrini çalıştı.

Onun yeni sürümü veya bu lib önceki sürümleri benzer davranış vardı emin değilim ama 2.6.6 için kesinlikle ek açıklama çalışması için Immutable POJO olması gerekir.

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

Yukarıda doğrudan küresel düzeyde ObjectMapper serileştirme dahil edilmesinin ayarlanması çeşitli cevaplarda belirtilen seçenek de çalışır, ancak ben sınıf veya dosyalanmış düzeyde kontrol etmeyi tercih ederim.

JSON serileştirme sırasında tüm boş alanların yok sayılmasını istiyorsanız, sınıf düzeyinde ek açıklamayı kullanın, ancak bir sınıfta yalnızca birkaç alanın yok sayılmasını istiyorsanız, o belirli alanlar üzerinde kullanın. Bu şekilde, belirli bir yanıt için davranışı değiştirmek isterseniz bakım için daha kolay okunabilir ve bakımı kolaydır.


2

Veya bu boş alanların otomatik olarak kaldırılacağı GSON'u [ https://code.google.com/p/google-gson/ ] kullanabilirsiniz .

SampleDTO.java

public class SampleDTO {

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

    // getters/setters
}

Test.java

import com.google.gson.Gson;

public class Test {

    public static void main(String[] args) {
        SampleDTO objSampleDTO = new SampleDTO();
        Gson objGson = new Gson();
        System.out.println(objGson.toJson(objSampleDTO));
    }
}

ÇIKTI:

{"isLoggedIn":false}

Kendimi kullanılmış GSON-2.2.4


-1

Boole türünü serileştirmeden hariç tutmak istiyorsanız aşağıdaki kod yardımcı olabilir:

@JsonInclude(JsonInclude.Include.NON_ABSENT)

1
Mevcut cevaplarla aynı
Karl Richter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.