Serialisierung mit Jackson (JSON) - "Kein Serializer gefunden"?

262

Ich bekomme die Ausnahme, wenn ich versuche, ein sehr einfaches Objekt mit Jackson zu serialisieren. Der Fehler:

org.codehaus.jackson.map.JsonMappingException: Für die Klasse MyPackage.TestA wurde kein Serializer gefunden und es wurden keine Eigenschaften zum Erstellen von BeanSerializer gefunden (um Ausnahmen zu vermeiden, deaktivieren Sie SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS).

Unten finden Sie die einfache Klasse und den Code zum Serialisieren.

Kann mir jemand sagen, warum ich diesen Fehler bekomme?

public class TestA {
    String SomeString = "asd";
}

TestA testA = new TestA();
ObjectMapper om = new ObjectMapper();
try {
    String testAString = om.writeValueAsString(testA); // error here!

    TestA newTestA = om.readValue(testAString, TestA.class);
} 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();
}
Ted
quelle
Ich habe einen Beitrag über das Schreiben eines benutzerdefinierten Serializers mit Jackson geschrieben , der für einige hilfreich sein kann.
Sam Berry

Antworten:

329

Wie bereits beschrieben, besteht die Standardkonfiguration einer ObjectMapperInstanz darin, nur auf Eigenschaften zuzugreifen, die öffentliche Felder sind oder öffentliche Getter / Setter haben. Eine Alternative zum Ändern der Klassendefinition, um ein Feld öffentlich zu machen oder einen öffentlichen Getter / Setter bereitzustellen, besteht darin, (gegenüber dem zugrunde liegenden VisibilityChecker) eine andere Sichtbarkeitsregel für Eigenschaften anzugeben . Jackson 1.9 bietet hierfür die ObjectMapper.setVisibility()bequeme Methode. Für das Beispiel in der ursprünglichen Frage würde ich dies wahrscheinlich als konfigurieren

myObjectMapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);

Für Jackson> 2.0:

myObjectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

Für weitere Informationen und Details zu verwandten Konfigurationsoptionen empfehle ich, die JavaDocs unter zuObjectMapper.setVisibility() überprüfen .

Programmierer Bruce
quelle
59
Das hat bei mir funktioniert. Ab Jackson 2.0 verwendet ObjectMapper # setVisibility einen PropertyAccessor als erstes Argument. Der entsprechende Oneliner ist myObjectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
Dan Robinson
@ DanRobinson habe ich gleich benutzt. Aber eigentlich generiere ich eine Yaml-Datei. Also für den JSONString als: {"term":{"call_failed":"true"}}Er generiert eine Yaml-Struktur als: filter: map: term: map: call_failed: "true"Warum generiert er ein mapSchlüsselwort? Wie kann ich es entfernen?
Manish Kumar
7
Ich habe wahrscheinlich 8 Stunden mit diesem Fehler verbracht und nicht bemerkt, dass meine Getter-Methode nicht "öffentlich" war. So dumm
Mike Kellogg
1
Ich erhalte diesen Fehler beim Konvertieren von ClientResponse in einen String mit Object Mapper
VdeX
1
Sie können auch die Anmerkung @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)über Ihrer Klasse hinzufügen
veben
74

Damit Jackson diese Klasse serialisieren kann, muss das SomeStringFeld entweder sein public(im Moment ist es Isolation auf Paketebene) oder Sie müssen Getter- und Setter-Methoden dafür definieren.

Chris
quelle
5
Bitte beachten Sie diese Antwort ist falsch - das Feld nicht nicht brauchen einen Getter und Setter öffentlich zu sein oder haben. In einer anderen Antwort auf diese Frage habe ich eine alternative Konfiguration bereitgestellt, bei der keine Änderungen an der ursprünglichen Datenstruktur (de) serialisiert werden müssen.
Programmierer Bruce
9
Die Antwort ist nützlich, auch wenn sie nicht zu 100% korrekt ist. Ich hatte vergessen, meine Vars "öffentlich" zu machen, und das wies darauf hin. Vielen Dank!
ChrisPhoenix
53

Ich habe das gleiche Problem in meinem Quellcode. Ich habe gerade hinzugefügt

Getter

und

Setter

das Problem gelöst.

Günay Gültekin
quelle
1
Versuchte viele verschiedene Dinge, und die Lösung ist so einfach wie diese ... und es heißt ganz klar: "Keine Eigenschaften entdeckt, um zu schaffen".
Aks
2
@PhilipRego Er meint, er hat einen Getter und Setter für das Feld hinzugefügt.
Paul
Ich benutze die Lombok-Bibliothek, also füge ich nur die Anmerkungen Getter und Setter hinzu. Und alles war gut. Vielen Dank.
Rahmat Hidayat
Ja, Getter und Setter werden für die Jackson-Serialisierung verwendet.
Deserialisierung
25

Das Problem in meinem Fall war, dass Jackson versuchte, ein leeres Objekt ohne Attribute oder Methoden zu serialisieren.

Wie in der Ausnahme vorgeschlagen, habe ich die folgende Zeile hinzugefügt, um Fehler bei leeren Beans zu vermeiden:

Für Jackson 1.9

myObjectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

Für Jackson 2.X.

myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

Sie finden ein einfaches Beispiel für Jackson Disable Fail_on_empty_Beans

Martín C.
quelle
9

Ich hatte das gleiche Problem für eine untergeordnete Klasse, in der ich die Kontrolle hatte. Der Objekt-Mapper befand sich in einem gemeinsamen Modul und war nicht zugänglich. Ich habe es gelöst, indem ich diese Anmerkung für meine untergeordnete Klasse hinzugefügt habe, deren Objekt serialisiert werden sollte.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
Pavan Kumar
quelle
7

Wenn Sie die Klasse bearbeiten können, die dieses Objekt enthält, füge ich normalerweise nur die Anmerkung hinzu

import com.fasterxml.jackson.annotation.JsonIgnore;

@JsonIgnore 
NonSerializeableClass obj;
ZiglioUK
quelle
2
Dieser Fehler wird auch ausgelöst, wenn Ihre Klasse eine Methode hat, deren Name mit get beginnt ... Zum Beispiel NonSerializableClass getMyNonSerializableObject (). Jackson versucht es zu serialisieren und schlägt fehl. Um dieses Problem zu beheben, fügen Sie einfach @JsonIgnore hinzu oder benennen Sie die Methode um.
Alexey Podlasov
1
Verwendet die ältere Version:org.codehaus.jackson.annotate.JsonIgnore
AlikElzin-kilaka
6

Dieser Fehler wird auch ausgelöst, wenn Sie vergessen, die Methode .build () zu Ihrem Rückgabestatus hinzuzufügen.

return Response.status(Status.OK);         // fails
return Response.status(Status.OK).build(); // works

Ich habe den folgenden Fehler ohne build () -Methode erhalten:

org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.sun.jersey.core.spi.factory.ResponseBuilderImpl
Patrics
quelle
4

SpringBoot2.0 , Ich löse es mit folgendem Code:

@Bean public ObjectMapper objectMapper() {
 return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);}
Janus
quelle
1
Sie sollten behalten, dass Ihr Modell Getter- und Setter-Methoden hat.
Janus
1
Willkommen bei SO! Vielen Dank für Ihren Beitrag. Bitte fügen Sie Ihrer Antwort eine Erklärung hinzu, damit klar ist, was der Code tut, warum er funktioniert und wie er die Frage des OP beantwortet.
Max Vollmer
Das hat mir geholfen! Aber meiner Meinung nach sollten Sie den ObjectMapper des Kontexts einfügen und anschließend konfigurieren, anstatt einen neuen zu erstellen.
RoBeaToZ
3

Fügen Sie für Oracle Java-Anwendungen Folgendes nach der ObjectMapperInstanziierung hinzu:

mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
LEMUEL ADANE
quelle
2

Ich hatte ein ähnliches Problem mit dem verzögerten Laden über das Proxy-Objekt im Ruhezustand. Ich habe es umgangen, indem ich die Klasse mit faulen geladenen privaten Eigenschaften mit folgenden Anmerkungen versehen habe:

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
N. berouain
quelle
Dies löste mein Problem. Können Sie mir sagen, was das genau macht?
Narbengesicht
2

Das Problem kann sein, dass Sie die Variable als deklariert haben private. Wenn Sie es ändern public, funktioniert es.

Eine bessere Option ist die Verwendung von Getter- und Setter-Methoden.

Dies wird das Problem lösen!

Sanchit Singhania
quelle
2

Ich habe mindestens drei Möglichkeiten gefunden, dies zu tun:

  1. Fügen Sie public gettersIhrer Entität hinzu, die Sie serialisieren möchten.
  2. Fügen Sie oben in der Entität eine Anmerkung hinzu, wenn Sie dies nicht möchten public getters. Dadurch wird die Standardeinstellung für Jackson dahingehend geändert Visbility=DEFAULT, @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)dass Zugriffsmodifikatoren akzeptiert werden.
  3. Ändern Sie Ihre ObjectMapperglobale Einstellung objectMapperInstance.setVisibility(JsonMethod.FIELD, Visibility.ANY);. Dies sollte vermieden werden, wenn Sie diese Funktionalität nicht global benötigen.

Wählen Sie basierend auf Ihren Bedürfnissen.

Georger
quelle
2

Hier sind die drei Optionen:

  1. Daten / Klassen, auf die zugegriffen wurde, müssen sein public
  2. Wenn nicht public, fügen Sie Getter & Setter hinzu
  3. Oder hinzufügen @JsonIgnore("context")
Santhosh Kumar
quelle
1

Bitte verwenden Sie dies auf Klassenebene für die Bohne:

@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
raveendra_bikkina
quelle
1

Das Hinzufügen von Setter und Getter löst auch das Problem, wie es für mich behoben wurde. Zum Beispiel:

public class TestA {
    String SomeString = "asd";

    public String getSomeString () {        return SomeString ;     }

    public void setSomeString (String SS ) {        SomeString = SS ;   } 
}
Satya Prakash
quelle
1

Ich hatte nur Getter, nachdem ich auch Setter hinzugefügt hatte, lösten sich die Probleme.

Vanita Dhotre
quelle
0

Obwohl ich Getter und Setter hinzugefügt habe, wurde der gleiche Fehler angezeigt. Später fand ich einen Fehler, dh nach Sonars Rat habe ich die Getter und Setter als geschützt eingestuft, was das Problem verursachte. Einmal habe ich behoben, dass es wie erwartet funktioniert hat.

Gelb
quelle
0

im Frühjahr Boot 2.2.5

nach dem Hinzufügen von Getter und Setter

Ich habe @JsonIgnore oben auf dem Feld hinzugefügt.

Saba
quelle