2

我们使用 Google Guice 进行 DI(主要使用构造函数注入)和 Jackson 用于与 JSON 的对象序列化。因此,我们通过 Guice 模块构建我们的对象图。

我们如何提供/指导 Jackson 使用我们预先构建的 Guice Injector?或者它是基于我们提供的 Guice 模块的自己的注入器?我的偏好是为它提供注入器,因为我们已经有办法根据我们想要运行的环境/配置来控制使用哪个模块。

这是一个单元测试:

public class Building {

    @JsonIgnore
    public final ElectricalProvider electricalProvider;

    public String name;

    @Inject
    Building(ElectricalProvider electricalProvider){
         this.electricalProvider = electricalProvider;
    }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

}

public interface ElectricalProvider {}

public class SolarElectricalProvider implements  ElectricalProvider{}

@Test
public void testJacksonGuice() throws IOException {

    Injector injector = Guice.createInjector(new Module() {
      @Override public void configure(Binder binder) {
           binder.bind(ElectricalProvider.class).to(SolarElectricalProvider.class);
      }
    });

    Building building1 = injector.getInstance(Building.class);
    building1.setName("test building");

    ObjectMapper objectMapper = new ObjectMapper();

    byte[] buildingJsonBytes = objectMapper.writeValueAsBytes(building1);

    Building building2 = objectMapper.readValue(buildingJsonBytes, Building.class);

    assertThat(building1, is(equalTo(building2)));
    assertThat(building2.electricalProvider, is(instanceOf(SolarElectricalProvider.class)));

}

运行时会生成此异常com.fasterxml.jackson.databind.JsonMappingException,并带有以下消息:找不到适合类型的构造函数 [简单类型,类建筑]:无法从 JSON 对象实例化(缺少默认构造函数或创建者,或者可能需要添加/启用类型信息?)

经过一番谷歌搜索,我遇到了jackson-module-guice项目,但它似乎不是我们需要的,也没有提供如何完成我们需要做的事情。

4

1 回答 1

0

好吧,我认为您的方法是反模式的。您应该只序列化和反序列化 POJO 对象,而不需要任何业务逻辑和任何进一步的依赖项,如服务、存储库等。你能展示你的Building班级吗?构造函数中有什么?

你应该把你的Building班级分成ServiceDomain层。该Service层将使用Domain,您应该在那里注入所有依赖项。该Domain层将只是具有默认构造函数的 POJO bean,没有最终字段,只有 getter/setter 方法。

如果您需要使用最终属性和构造函数初始化,您几乎没有杰克逊 3rd Party Class With No Default Constructor中提到的选项

于 2015-06-05T11:00:18.207 回答