Jackson ile seri hale getirme (JSON) - “Serileştirici bulunamadı”?


262

Jackson kullanarak çok basit bir nesneyi serileştirmeye çalışırken bir istisna alıyorum. Hata:

org.codehaus.jackson.map.JsonMappingException: MyPackage.TestA sınıfı için serileştirici bulunamadı ve BeanSerializer oluşturmak için keşfedilen özellik yok (istisnayı önlemek için SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS özelliğini devre dışı bırakın)

Serileştirilecek basit sınıf ve kod aşağıdadır.

Biri neden bu hatayı aldığımı söyleyebilir mi?

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

Jackson'a bazılarına yardımcı olabilecek özel bir Serializer Yazma hakkında bir yazı yazdım .
— Sam Berry

Yanıtlar:


329

Daha önce açıklandığı gibi, bir ObjectMapperörneğin varsayılan yapılandırması yalnızca ortak alanlar olan veya genel alıcılar / ayarlayıcılara sahip özelliklere erişmektir. Bir alanı herkese açık hale getirmek veya genel bir alıcı / ayarlayıcı sağlamak için sınıf tanımını değiştirmenin bir alternatifi (altta yatan VisibilityChecker) farklı bir özellik görünürlük kuralı belirlemektir. Jackson 1.9 ObjectMapper.setVisibility()bunu yapmak için kolaylık yöntemi sağlar . Orijinal sorudaki örnek için, bunu muhtemelen

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

Jackson> 2.0 için:

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

İlgili yapılandırma seçenekleriyle ilgili daha fazla bilgi ve ayrıntı için JavaDoc'larıObjectMapper.setVisibility() incelemenizi öneririz .


59
Bu benim için çalıştı. Jackson 2.0'dan itibaren, ObjectMapper # setVisibility ilk bağımsız değişken olarak bir PropertyAccessor alır. Eşdeğer oneliner myObjectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
— Dan Robinson

@DanRobinson Ben de kullandım. Ama aslında yaml dosyası üretiyorum. JSONString için as: {"term":{"call_failed":"true"}}bu gibi yaml yapısı üretiyor: filter: map: term: map: call_failed: "true"Neden mapanahtar kelime üretiyor ? Nasıl kaldırabilirim?
— Manish Kumar

7
Muhtemelen bu hatayla 8 saat geçirdim, benim alıcı yöntemi üzerinde "kamu" yoktu farkında değil .. çok aptal
— Mike Kellogg

1
Nesne eşleyici kullanarak ClientResponse dizeye dönüştürürken bu hatayı alıyorum
— VdeX

1
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)Sınıfınıza ek açıklama da ekleyebilirsiniz
— veben

74

Jackson'ın bu sınıfı serileştirmesi için SomeStringalanın public(şu anda paket düzeyinde izolasyonu) olması veya bunun için alıcı ve ayarlayıcı yöntemlerini tanımlamanız gerekir.


5
Bu cevabın yanlış olduğunu lütfen unutmayın - alanın herkese açık olması veya alıcı ve ayarlayıcı olması gerekmez . Bu soruya verilecek başka bir cevapta, orijinal veri yapısında (de) serileştirilmeyi gerektirmeyen alternatif bir yapılandırma sağladım.
— Programcı Bruce

9
% 100 tam olarak doğru olmasa bile cevap faydalıdır. Varyasyonlarıma 'kamuoyu' koymayı unutmuştum ve bu işaret etti. Teşekkürler!
— ChrisPhoenix

53

Kaynak kodumda da aynı sorun var. Yeni ekledim

gaz giderici

ve

setter

sorun çözüldü.


1
Birçok farklı şey denedim ve çözüm bu kadar basit .... ve açıkça açıkça söylüyor: "oluşturmak için hiçbir özellik keşfedilmedi".
— aks

2
@PhilipRego Alan için bir alıcı ve ayarlayıcı eklediği anlamına geliyor.
— Paul

Lombok kütüphanesini kullanıyorum, bu yüzden sadece Getter ve Setter eklerini ekliyorum. Ve her şey iyiydi. Teşekkürler.
— Rahmat Hidayat

evet, Alıcılar ve ayarlayıcılar Jackson serialization./deserialization kullanılmaktadır
— Ikhiloya Imokhai

25

Benim durumumda Jackson hiçbir özelliği veya yöntemi ile boş bir nesneyi serileştirmeye çalışıyordu.

İstisnada önerildiği gibi, boş fasulyelerde başarısızlığı önlemek için aşağıdaki satırı ekledim:

Jackson 1.9 için

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

Jackson 2.X için

myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

Jackson enable fail_on_empty_beans üzerinde basit bir örnek bulabilirsiniz


9

Aynı problemi kontrol ettiğim bir çocuk sınıfı için de yaşadım, nesne eşleyici ortak bir modüldeydi ve erişilemezdi. Nesnenin serileştirilmesi gereken çocuk sınıfım için bu ek açıklamayı ekleyerek çözdüm.

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)

7

Bu nesneyi içeren sınıfı düzenleyebiliyorsanız, genellikle ek açıklama eklerim

import com.fasterxml.jackson.annotation.JsonIgnore;

@JsonIgnore 
NonSerializeableClass obj;

2
Sınıfınızda get ile başlayan ada sahip bir yöntem olduğunda da bu hata tetiklenir ... Örneğin NonSerializableClass getMyNonSerializableObject (). Jackson bunu serileştirmeye çalışır ve başarısız olur. Bu sorunu gidermek için @JsonIgnore ekleyin veya yöntemi yeniden adlandırın.
— Alexey Podlasov

1
Eski sürümü kullandı:org.codehaus.jackson.annotate.JsonIgnore
— AlikElzin-kilaka

6

Geri dönüş durumunuza .build () yöntemini eklemeyi unutursanız da bu hata atılır.

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

Ben build () yöntemi olmadan aşağıdaki hatayı aldım:

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

4

SpringBoot2.0 follow Takip koduyla çözdüm:

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

1
modelinizin alıcı ve ayarlayıcı yöntemlerine sahip olmasını sağlamalısınız.
— Janus

1
SO hoş geldiniz! Katkınız için teşekkürler. Lütfen cevabınıza bir açıklama ekleyin, bu nedenle kodun ne yaptığını, neden çalıştığını ve OPs sorusunu nasıl yanıtladığını net bir şekilde ortaya koyun.
— Max Vollmer

Bu bana yardımcı oldu! Ama bence, bağlamın ObjectMapper'ını enjekte etmeli ve daha sonra yeni bir tane oluşturmak yerine yapılandırmalısınız.
— RoBeaToZ

3

Oracle Java uygulamaları için bunu ObjectMapperörneklemeden sonra ekleyin :

mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

2

Hazırda bekleme proxy nesnesi aracılığıyla tembel yükleme ile benzer bir sorun vardı. Tembel yüklenen özel mülklere sahip sınıfa açıklama ekleyerek aşağıdakileri yapın:

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

Bu benim sorunumu çözdü. Bunun tam olarak ne yaptığını söyleyebilir misiniz?
— scarface

2

Sorun değişken olarak bildirmiş olmanız olabilir private. Bunu olarak değiştirirseniz publicçalışır.

Daha iyi bir seçenek bunun için alıcı ve ayarlayıcı yöntemlerini kullanmaktır.

Bu sorunu çözecektir!


2

Bunu yapmanın en az üç yolunu buldum:

  1. public gettersSerileştirmeye çalıştığınız varlığınıza ekleyin ;
  2. İstemiyorsanız, varlığın üstüne bir ek açıklama ekleyin public getters. Bu gelen Jackson için varsayılan değişecek Visbility=DEFAULTiçin @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)herhangi erişim düzenleyiciler kabul edildiği;
  3. Ayarlayarak ObjectMapperküresel değiştirin objectMapperInstance.setVisibility(JsonMethod.FIELD, Visibility.ANY);. Küresel olarak bu işlevselliğe ihtiyacınız yoksa bundan kaçınılmalıdır.

İhtiyaçlarınıza göre seçin.


2

İşte üç seçenek:

  1. Erişilen veri / sınıfın public
  2. Değilse public, alıcılar ve ayarlayıcılar ekleyin
  3. Veya ekle @JsonIgnore("context")

1

Fasulye için lütfen bunu sınıf düzeyinde kullanın:

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

1

ayarlayıcı ve alıcı eklemek de sorunu benim için çözdüğü gibi çözecektir. Örn:

public class TestA {
    String SomeString = "asd";

    public String getSomeString () {        return SomeString ;     }

    public void setSomeString (String SS ) {        SomeString = SS ;   } 
}


0

Getters ve setters ekledim rağmen aynı hatayı alıyordum. Sonra bir hata buldum. Bir kez düzeltildiği gibi çalıştığını sabitledim.


0

bahar çizme 2.2.5

alıcı ve ayarlayıcı ekledikten sonra

Ben alanın üstüne @JsonIgnore ekledi.

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.