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.