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

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 .


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.


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.


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


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)

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;

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

4

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

@Bean public ObjectMapper objectMapper() {
 return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);}

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

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

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!


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.


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

1

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

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

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

1

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


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.


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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.