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

Ted*_*Ted 248 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();
}
Run Code Online (Sandbox Code Playgroud)

Pro*_*uce 314

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

myObjectMapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);
Run Code Online (Sandbox Code Playgroud)

有关相关配置选项的更多信息和详细信息,建议您查看JavaDocsObjectMapper.setVisibility().

  • 这对我有用.从Jackson 2.0开始,ObjectMapper#setVisibility将PropertyAccessor作为第一个参数.等价的oneliner是`myObjectMapper.setVisibility(PropertyAccessor.FIELD,Visibility.ANY);` (59认同)
  • 我可能花了8个小时来处理这个错误,没有意识到我的getter方法没有"公开"...所以愚蠢 (5认同)
  • 您还可以在类上方添加注释“@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)” (4认同)

Chr*_*ris 72

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

  • 答案很有用,即使不是100%精确正确.我忘了把'公开'放在我的变种上,这就指出了这一点.谢谢! (9认同)
  • 请注意这个答案是不正确的 - 该字段不需要*公开或有吸气剂和二传手.在这个问题的另一个答案中,我提供了一种替代配置,它不需要对原始数据结构进行更改(de)序列化. (5认同)

Gün*_*kin 49

我的源代码中存在同样的问题.我刚才补充道

吸气

二传手

问题解决了.

  • 单独添加 Getters 就解决了我的问题,无需添加 setters (5认同)
  • 尝试了很多不同的事情,解决方案就这么简单......并且它说得很清楚:“没有发现可以创建的属性”。 (4认同)
  • 我使用lombok库,所以我只添加注释Getter和Setter。一切都很好。谢谢。 (3认同)
  • @PhilipRego他的意思是他为该领域添加了一个吸气剂和吸气剂。 (2认同)
  • 是的,getter 和 setter 用于 Jackson 序列化/反序列化 (2认同)

Mar*_*n C 25

我的问题是杰克逊试图序列化一个没有属性和方法的空对象.

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

杰克逊1.9

myObjectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
Run Code Online (Sandbox Code Playgroud)

对于Jackson 2.X

myObjectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
Run Code Online (Sandbox Code Playgroud)

你可以在jackson上找到一个简单的例子,禁用fail_on_empty_beans


Nak*_*esh 11

Jackson 使用 getter 和 setter 序列化/反序列化。因此,在模型类中添加 getter 和 setter。


Pav*_*mar 9

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

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
Run Code Online (Sandbox Code Playgroud)


pat*_*ics 6

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

return Response.status(Status.OK);         // fails
return Response.status(Status.OK).build(); // works
Run Code Online (Sandbox Code Playgroud)

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

org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.sun.jersey.core.spi.factory.ResponseBuilderImpl
Run Code Online (Sandbox Code Playgroud)


Zig*_*oUK 6

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

import com.fasterxml.jackson.annotation.JsonIgnore;

@JsonIgnore 
NonSerializeableClass obj;
Run Code Online (Sandbox Code Playgroud)

  • 当您的类具有以get开头的名称的方法时,也会触发此错误。例如NonSerializableClass getMyNonSerializableObject()。杰克逊试图序列化它,但失败了。要解决此问题,只需添加@JsonIgnore或重命名该方法。 (2认同)

小智 6

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

@Bean public ObjectMapper objectMapper() {
 return new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);}
Run Code Online (Sandbox Code Playgroud)

  • 欢迎来到SO!感谢您的贡献。请在您的答案中添加解释,以便清楚地了解代码的作用、其工作原理以及它如何回答操作员的问题。 (2认同)

geo*_*ger 5

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

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

根据您的需求进行选择。