如何在不修改接口的情况下在Jackson中实现抽象类型?

dgtucam1  于 7个月前  发布在  其他
关注(0)|答案(1)|浏览(76)

我正在开发一个Java应用程序,它利用Jackson库进行JSON格式化。我有一个名为LayoutBlock的抽象类,它表示Slack的消息布局中的一个块。该应用程序使用自定义LayoutBlockDataAliizer基于“type”属性将JSON数据转换为LayoutBlock的特定子类。
然而,在运行测试时,我遇到了以下异常:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.slack.api.model.block.LayoutBlock` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information

由于项目中的限制,我没有修改LayoutBlock接口以添加任何Jackson注解(如@JsonTypeInfo或@JsonSubTypes)的权限。我如何解决这个问题,并成功地将JSON转换为LayoutBlock的适当子类,而不修改LayoutBlock接口?
下面是我的代码的概述:

LayoutBlocks验证器:

public class LayoutBlockDeserializer extends JsonDeserializer<LayoutBlock> {
// ... implementation details
}

Slack模块:

public class SlackModule extends SimpleModule {

   @Override
   public void setupModule(SetupContext context) {
      addDeserializer(LayoutBlock.class, new 
      LayoutBlockDeserializer());
   }
}

测试:

@Test
void test() throws JsonProcessingException {
   ObjectMapper mapper = new ObjectMapper().registerModule(new SlackModule());
   mapper.readValue("any-json-here", LayoutBlock.class);
}

我将非常感谢任何能够帮助我处理Jackson中抽象类型的抽象化而无需修改LayoutBlock接口或向其添加注解的见解或替代方法。在此先谢谢您!

kadbb459

kadbb4591#

你可以用mixin来解决这个问题:

@JsonDeserialize(using = LayoutBlockDeserializer.class)
public class MixInForLayoutBlock {}

通过mapper.addMixIn(LayoutBlock.class, MixInForLayoutBlock.class);使用它不要忘记使用@JsonDeserialize(as = LayoutBlockImpl.class)注解LayoutBlock实现(或者也使用mixin)。
如果您在使用一个编译器实现时遇到困难,here是一个很好的解决方案。

相关问题