webentwicklung-frage-antwort-db.com.de

Jackson-Serialisierung: Ignoriere leere Werte (oder null)

Ich verwende derzeit jackson 2.1.4 und habe einige Probleme beim Ignorieren von Feldern, wenn ich ein Objekt in einen JSON-String konvertiere.

Hier ist meine Klasse, die als zu konvertierendes Objekt fungiert:

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

Und so konvertiere ich es:

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

Hier ist die Ausgabe:

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

Wie kann ich diese Nullwerte vermeiden? Ich möchte nur die erforderlichen Informationen für den "Abonnement" -Zweck verwenden!

Hier ist genau die Ausgabe, die ich suche:

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

Ich habe auch versucht, @JsonInclude (Include.NON_NULL) und alle meine Variablen auf Null zu setzen, aber es hat auch nicht funktioniert! Danke für eure Hilfe!

128
Shinnyx

Sie haben die Anmerkung an der falschen Stelle - sie muss sich auf der Klasse befinden, nicht auf dem Feld. d.h.

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

Wie in den Kommentaren erwähnt, lautet die Syntax für diese Annotation in Version 2.x +:

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

Die andere Möglichkeit besteht darin, den ObjectMapper direkt zu konfigurieren, indem Sie einfach mapper.setSerializationInclusion(Include.NON_NULL); aufrufen.

(Ich denke, die Popularität dieser Antwort ist ein Hinweis darauf, dass diese Anmerkung sollte feldweise anwendbar ist * ahem @ fasterxml *)

226
awqueous

Sie können auch die globale Option festlegen:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
44
nomad

Sie können auch versuchen, zu verwenden

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

wenn Sie es mit Jackson mit einer Version unter 2+ (1.9.5) zu tun haben, die ich getestet habe, können Sie diese Anmerkung leicht über der Klasse verwenden. Nicht für die Attribute angegeben, nur für die Klassendeklaration.

15
erhanasikoglu

Sie müssen import com.fasterxml.jackson.annotation.JsonInclude hinzufügen.

Hinzufügen

@JsonInclude(JsonInclude.Include.NON_NULL)

auf POJO

Wenn Sie POJO dann geschachtelt haben

@JsonInclude(JsonInclude.Include.NON_NULL)

müssen auf alle Werte hinzufügen.

HINWEIS: JAXRS (Jersey) behandelt dieses Szenario 2.6 und höher automatisch.

12
vaquar khan

Für Jackson 2.x

@JsonInclude (JsonInclude.Include.NON_NULL) direkt vor dem Feld.

3
Gere

Ich hatte kürzlich ein ähnliches Problem mit Version 2.6.6.

@JsonInclude(JsonInclude.Include.NON_NULL)

Die Verwendung der obigen Annotation auf Feld- oder Klassenebene funktionierte nicht wie erwartet. Das POJO war veränderlich, wo ich die Anmerkung anwendete. Als ich das Verhalten des POJO so änderte, dass es unveränderlich war, wirkte die Annotation magisch.

Ich bin nicht sicher, ob die neue Version oder frühere Versionen dieser Bibliothek ein ähnliches Verhalten aufwiesen, aber für 2.6.6 benötigen Sie mit Sicherheit Immutable POJO, damit die Annotation funktioniert.

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

Die obige Option, die in verschiedenen Antworten zum Einrichten der Serialisierung in ObjectMapper direkt auf globaler Ebene erwähnt wurde, funktioniert ebenfalls, ich bevorzuge jedoch die Steuerung auf Klassen- oder Ordnerebene.

Wenn Sie also möchten, dass alle Nullfelder während der JSON-Serialisierung ignoriert werden, verwenden Sie die Annotation auf Klassenebene. Wenn Sie jedoch möchten, dass nur wenige Felder in einer Klasse ignoriert werden, verwenden Sie sie über diesen bestimmten Feldern. Auf diese Weise ist es lesbarer und wartungsfreundlicher, wenn Sie das Verhalten für eine bestimmte Reaktion ändern möchten.

2
Amrut

Alternativ können Sie GSON [ https://code.google.com/p/google-gson/ ] verwenden, wobei diese Nullfelder automatisch entfernt werden.

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

AUSGABE:

{"isLoggedIn":false}

Ich habe gson-2.2.4 verwendet

2
anij

Der folgende Code kann hilfreich sein, wenn Sie den Booleschen Typ von der Serialisierung ausschließen möchten:

@JsonInclude(JsonInclude.Include.NON_ABSENT)
0
Alexander