Jackson – JsonMappingException (缺少序列化器)

Data,Jackson
Remote
0
01:25 AM · Dec 01 ,2025

1. 概述

在本快速教程中,我們將分析沒有獲取器且解決 Jackson JsonMappingException異常的解決方案

如果您想深入瞭解以及學習 Jackson 2 中您可以做的事情 – 請訪問主 Jackson 教程。

2. 問題

默認情況下,Jackson 2 只會與具有公共訪問權限或具有公共 getter 方法的字段一起工作——將具有所有字段私有或包私有訪問權限的實體進行序列化將會失敗

public class MyDtoNoAccessors {
    String stringValue;
    int intValue;
    boolean booleanValue;

    public MyDtoNoAccessors() {
        super();
    }

    // 沒有 getter 方法
}
@Test(expected = JsonMappingException.class)
public void givenObjectHasNoAccessors_whenSerializing_thenException()
  throws JsonParseException, IOException {
    String dtoAsString = new ObjectMapper().writeValueAsString(new MyDtoNoAccessors());

    assertThat(dtoAsString, notNullValue());
}
The 完整的異常是:
com.fasterxml.jackson.databind.JsonMappingException: 
No serializer found for class dtos.MyDtoNoAccessors 
and no properties discovered to create BeanSerializer 
(to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) )

3. 解決方案顯而易見的是添加對字段的獲取器——如果實體在我們控制之下。如果情況並非如此,並且無法修改實體的源——那麼 Jackson 為我們提供了幾個替代方案。

3.1. 全局自動檢測所有可見字段的字段一種解決此問題的方案是全局配置 ObjectMapper 以檢測所有字段,無論其可見性如何:

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

這將允許私有和包私有字段被檢測,而無需獲取器,並且序列化將正常工作:

@Test
public void givenObjectHasNoAccessors_whenSerializingWithAllFieldsDetected_thenNoException()
  throws JsonParseException, IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
    String dtoAsString = objectMapper.writeValueAsString(new MyDtoNoAccessors());

    assertThat(dtoAsString, containsString("intValue"));
    assertThat(dtoAsString, containsString("stringValue"));
    assertThat(dtoAsString, containsString("booleanValue"));
}

3.2. 檢測所有字段在類級別Jackson 2 提供的另一個選項是——而不是全局配置——通過使用 @JsonAutoDetect 註解在類級別控制字段可見性

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class MyDtoNoAccessors { ... }

使用此註解,序列化應該現在可以正確地與此特定類一起工作:

@Test
public void givenObjectHasNoAccessorsButHasVisibleFields_whenSerializing_thenNoException()
  throws JsonParseException, IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    String dtoAsString = objectMapper.writeValueAsString(new MyDtoNoAccessors());

    assertThat(dtoAsString, containsString("intValue"));
    assertThat(dtoAsString, containsString("stringValue"));
    assertThat(dtoAsString, containsString("booleanValue"));
}

4. 禁用 fail_on_empty_beans 在 Jackson 中

在 Jackson 中,fail_on_empty_beans 功能確定如果一個在序列化時為空的對象(沒有屬性)是否應該拋出異常。 默認情況下,Jackson 在遇到空 Bean 時會拋出異常。

值得注意的是,fail_on_empty_beans 功能默認啓用,因此如果我們想要禁用它,則需要顯式將其設置為 false。 可以通過兩種方式來實現,具體取決於我們的特定用例。

4.1. 使用 Object Mapper 配置

我們可以使用 ObjectMapper 顯式地禁用 fail_on_empty_beans

ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

通過這種方式配置 ObjectMapper,我們告訴 Jackson 在遇到空 Bean 時不拋出異常。

4.2. 使用 Spring Boot

在 Spring Boot 中,我們可以將以下屬性在 application.properties 文件中設置,以全局禁用 fail_on_empty_beans

spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false

此屬性可以設置為應用程序級別,以控制整個應用程序中 Jackson 序列化的行為。

5. 結論

本文介紹瞭如何繞過 Jackson 的默認字段可見性,通過在 ObjectMapper 全局或單個類上配置自定義可見性。Jackson 允許更進一步的自定義,通過提供選項來控制映射器如何看待獲取器、設置器或具有特定可見性的字段。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.