使用Jackson(JSON)序列化 - 获得“没有找到序列化器”?

时间:2011-12-03 11:26:13

标签: java json jackson

我尝试使用Jackson序列化一个非常简单的对象时遇到异常。错误:

  

org.codehaus.jackson.map.JsonMappingException:找不到序列化程序   类MyPackage.TestA并没有属性   发现创建BeanSerializer(以避免异常,禁用   SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS))

下面是序列化的简单类和代码。

有谁可以告诉我为什么会收到此错误?

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

19 个答案:

答案 0 :(得分:285)

如前所述,ObjectMapper实例的默认配置是仅访问属于公共字段或具有公共getter / setter的属性。更改类定义以使字段公开或提供公共getter / setter的替代方法是指定(对于基础VisibilityChecker)不同的属性可见性规则。 Jackson 1.9为此提供了ObjectMapper.setVisibility()便利方法。对于原始问题中的示例,我可能将其配置为

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

杰克逊> 2.0:

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

有关相关配置选项的详细信息和详细信息,建议您查看the JavaDocs on ObjectMapper.setVisibility()

答案 1 :(得分:65)

对于Jackson序列化该类,SomeString字段需要为public(现在它的包级别隔离),或者您需要为它定义getter和setter方法。

答案 2 :(得分:37)

我的源代码中存在同样的问题。我刚刚添加了

  

吸气剂

  

设定器

问题解决了。

答案 3 :(得分:22)

我的案例中的问题是杰克逊试图序列化一个没有属性或方法的空对象。

正如异常中所建议的,我添加了以下行以避免空bean失败:

杰克逊1.9

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

杰克逊2.X

myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

您可以在jackson disable fail_on_empty_beans

上找到一个简单的示例

答案 4 :(得分:7)

对于我控制的子类,我遇到了同样的问题,对象映射器在一个公共模块中并且无法访问。我通过为我的子类添加这个注释来解决它,这个注释的对象是序列化的。

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)

答案 5 :(得分:6)

如果您可以编辑包含该对象的类,我通常只需添加注释

import com.fasterxml.jackson.annotation.JsonIgnore;

@JsonIgnore 
NonSerializeableClass obj;

答案 6 :(得分:5)

如果您忘记将.build()方法添加到返回状态,也会抛出此错误。

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

没有build()方法我得到以下错误:

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

答案 7 :(得分:3)

问题可能是因为您已将变量声明为private。 如果您将其更改为public,则会有效。

更好的选择是使用getter和setter方法。

这将解决问题!

答案 8 :(得分:3)

对于Oracle Java应用程序,请在ObjectMapper实例化后添加:

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

答案 9 :(得分:2)

这是三个选项:

  1. 已访问的数据/类必须为public
  2. 如果不是public,请添加获取器和设置器
  3. 或添加@JsonIgnore("context")

答案 10 :(得分:1)

我只是只有吸气剂,也添加了setter之后,问题解决了。

答案 11 :(得分:1)

添加setter和getter也将解决我所解决的问题。 例如:

public class TestA {
    String SomeString = "asd";

    public String getSomeString () {        return SomeString ;     }

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

答案 12 :(得分:1)

SpringBoot2.0,我通过以下代码来解决它:

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

答案 13 :(得分:1)

我发现至少有三种方法可以做到这一点:

  1. 在要序列化的实体上添加public getters
  2. 如果不想使用public getters,请在实体顶部添加注释。这会将Jackson的默认设置从Visbility=DEFAULT更改为@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY),接受任何访问修饰符;
  3. 通过设置ObjectMapper全局更改objectMapperInstance.setVisibility(JsonMethod.FIELD, Visibility.ANY);。如果您全局上不需要此功能,则应避免这种情况。

根据您的需求选择。

答案 14 :(得分:1)

我在通过hibernate代理对象进行延迟加载时遇到了类似的问题。通过使用:

注释具有延迟加载的私有属性的类来解决它
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

答案 15 :(得分:0)

在春季靴2.2.5中

添加getter和setter之后

我在该字段的顶部添加了@JsonIgnore。

答案 16 :(得分:0)

如果您使用 Lomdok 库 (https://projectlombok.org/),则将 @Data (https://projectlombok.org/features/Data) 注释添加到您的数据对象类。

答案 17 :(得分:0)

请在类级别使用该bean:

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

答案 18 :(得分:0)

虽然我添加了getter和setter但是我得到了同样的错误。后来我发现了一个错误,就是通过Sonar的建议,我把吸气剂和安装者视为受保护的,这导致了这个问题。一旦我修复它,它就像预期一样工作。