假设我们有以下课程:

public abstract class Investment {

   private String investmentType;

   // getters & setters
}

public class Equity extends Investment {
}

public class Bond extends Investment {
}

public class InvestmentFactory {

    public static Investment getTypeFromString(String investmentType) {
        Investment investment = null;
        if ("Bond".equals(investmentType)) {
            investment = new Bond();
        } else if ("Equity".equals(investmentType)) {
            investment = new Equity();
        } else {
            // throw exception
        }
        return investment;
    }
}

以及以下@RestController:
@RestController
public class InvestmentsRestController {

    private InvestmentRepository investmentRepository;

    @Autowired
    public InvestmentsRestController(InvestmentRepository investmentRepository) {
        this.investmentRepository = investmentRepository;
    }

    @RequestMapping(RequestMethod.POST)
    public List<Investment> update(@RequestBody List<Investment> investments) {
       return investmentRepository.update(investments);
    }

}

以及请求正文中的以下json:
[
  {"investmentType":"Bond"},
  {"investmentType":"Equity"}
]

如何在抽象类List<Investment>上不使用Jackson的@JsonSubTypes的情况下,将json绑定或转换为Investment的请求正文,而使用InvestmentFactory呢?

最佳答案

@JsonDeserialize的效果很好,但是如果您除了类型以外还有更多的字段,则必须手动设置它们。如果您要回到 jackson ,可以使用:

投资类

    @JsonTypeInfo(
            use = JsonTypeInfo.Id.NAME,
            include = JsonTypeInfo.As.PROPERTY,
            property = "investmentType")
    @JsonTypeIdResolver(InvestmentResolver.class)
    public abstract class Investment {
    }

InvestmentResolver.class
public class InvestmentResolver extends TypeIdResolverBase {

    @Override
    public JavaType typeFromId(DatabindContext context, String id) throws IOException {
        Investment investment = InvestmentFactory.getTypeFromString(type);
        return context.constructType(investment.getClass());
    }

这样做的好处是,如果您开始向“投资”中添加字段,则不必在Desrializer中添加它们(至少在我的情况下是这样),但 jackson 会为您处理。因此,明天您可以拥有测试用例:
'[{"investmentType":"Bond","investmentName":"ABC"},{"investmentType":"Equity","investmentName":"APPL"}]'

你应该很好走!

08-08 00:45