在一个Spring Boot应用程序中使用两个不同配置的ObjectMapper

时间:2017-06-29 12:52:48

标签: json spring spring-boot jackson mapping

我正在开发一个中间件应用程序,它将通过RestTemplate接收的值反序列化为来自遗留API的json-String(因此,对“他们的”数据模型没有影响,因此需要为我的objectmapper使用这个api的一些自定义配置) ,应用程序本身也提供了一个基于legacydata作为json的(部分丰富和合成)数据的宁静API。

现在,我的遗留映射类的构造函数目前都在共享这样的通用结构:

    ...
    private ObjectMapper mapper;

    public MyMapper() {
        this.mapper = new ObjectMapper();
        this.mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
        this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }
    ...

因为我使用杰克逊从legacysystem反序列化json。基本上我想使用Springs DI Container重构这种冗余。

所以我尝试创建自己的Objectmapper @Component,它只是扩展ObjectMapper,就像在这个帖子的一些答案中所说的那样: Configuring ObjectMapper in Spring - 让我们调用它FromLegacyObjectMapper - 而不是在每个类中初始化我的映射器,所以我创建了一个并使用了

@Autowired
private FromLegacyObjectMapper

(或构造函数注释 - 等效,但为了简单起见..)。 但这有一些严重的副作用。实际上,由于rootvalue-wrapped,我无法将clientjson反序列化到我的控制器中的视图模型,因为自动装配会覆盖我从前端反序列化viewModel时实际需要的spring引导标准objectmapper。

我试着让它像这样运行起来:

frontend <---> My Api using Standard ObjectMapper <--> viewModel created by consuming legacy-Api-json using FromLegacyObjectMapper

所以,我当然可以做的是为我的映射类使用基类,只需将上面的代码添加到基础构造函数中,让每个Mapperclass扩展这个基础,但实际上我希望找到一种方法来使用spring依赖注入容器代替。我现在没有想法,所以我希望有人可以帮助我!

编辑:为了让它更清晰一点,请参阅下面的Moritz回答以及我们在评论中的讨论。我很清楚我能够使用@Qualifier注释,但如果有办法将@Qualifier添加到spring控制器中使用的标准objectmapper,这只会解决问题。我会自己做一些研究,但其他答案非常受欢迎。

1 个答案:

答案 0 :(得分:1)

我会尝试将两个不同的ObjectMapper添加到Spring容器中。你可以添加这样的东西,例如你的Application类(假设这是用@SpringBootApplication注释的那个):

@Bean
@Qualifier("fromLegacy")
public ObjectMapper fromLegacyObjectMapper() {

  // create and customize your "from legacy" ObjectMapper here

  return objectMapper;
}

@Bean
@Qualifier("default")
public ObjectMapper defaultObjectMapper() {

  // create your default ObjectMapper here

  return objectMapper;
}

然后,您可以在使用旧API的类中注入“from legacy”ObjectMapper,如下所示:

public class SomeServiceUsingLegacyApi {

    private final ObjectMapper objectMapper;

    @Autowired
    public SomeServiceUsingLegacyApi(@Qualifier("fromLegacy") ObjectMapper objectMapper) {

      this.objectMapper = objectMapper;
    }

    // [...]
}

在其他课程中,相应地使用其他API:

public class SomeServiceUsingOtherApi {

  private final ObjectMapper objectMapper;

  @Autowired
  public SomeServiceUsingOtherApi(@Qualifier("default") ObjectMapper objectMapper) {

    this.objectMapper = objectMapper;
  }

  // [...]
}