使用@JsonUnwrapped 并具有自定义序列化程序 (StdSerializer<T>)

Using @JsonUnwrapped and having a custom Serializer (StdSerializer<T>)

我需要为我的实体“付款”之一编写一个自定义序列化程序,我必须通过扩展 StdSerializer:

来实现它
class Payment {
}

class PaymentSerializer extends StdSerializer<Payment> {

    public PaymentSerializer() {
        this(null);
    }

    public PaymentSerializer(Class<Payment> t) {
        super(t);
    }

    @Override
    public void serialize(Payment value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // some logics
    }

}

因为我使用 Spring,所以我注册了这个 Serializer,所以 Spring 可以识别它:

@Bean
public Jackson2ObjectMapperBuilder serializersObjectMapperBuilder() {
    SimpleModule module = new SimpleModule();
    module.addSerializer(Payment.class, applicationContext.getBean(PaymentSerializer.class));
    return new Jackson2ObjectMapperBuilder().modules(module);
}

现在我有一个控制器,可以 returns 将数据返回给客户端,它可以毫无问题地使用这个序列化程序:

@RestController
@RequestMapping("/payment")
class PaymentController {

    @GetMapping
    public List<Payment> getAll() {
        return Arrays.asList(new Payment());
    }

}

从现在开始,我的 Serializer 工作正常,一切都很好。

问题出在另一个实体“订单”上,它的付款方式是 属性,@JsonUnwrapped:

class Order {

    @JsonUnwrapped
    private Payment payment;

}

我需要打开 Order 中的 Payment 并且我想使用 相同的 PaymentSerializer 但问题是当我使用这个自定义序列化程序时, @JsonUnwrapped 注释将被忽略,输出将是这样的:

{
  "payment": {
    .....
  }
}

正如我提到的,我想删除“付款”字段并将其解包。 我知道要为自定义序列化器模拟 @JsonUnwrapped,我需要扩展 UnwrappingBeanSerializer class,但正如我一开始提到的,我也需要标准序列化器。

我无法更改我的实体模型。

有什么办法可以做到吗?

我使用 Spring Boot 2.1.3.RELEASE 我相信它使用 Jackson 2.9

我提出以下解决问题的方法: 我们可以在单个自定义序列化程序中组合两个 StdSerializer

@Component
class PaymentSerializer extends StdSerializer<Payment> {

    private final JsonSerializer<Payment> delegate = new UnwrappingPaymentSerializer(NameTransformer.NOP);

    public PaymentSerializer() {
        this(null);
    }

    public PaymentSerializer(Class<Payment> t) {
        super(t);
    }

    @Override
    public void serialize(Payment value, JsonGenerator generator, SerializerProvider provider) throws IOException {
        generator.writeStartObject();
        this.delegate.serialize(value, generator, provider);
        generator.writeEndObject();
    }

    @Override
    public JsonSerializer<Payment> unwrappingSerializer(final NameTransformer nameTransformer) {
        return new UnwrappingPaymentSerializer(nameTransformer);
    }

}

并展开:

public class UnwrappingPaymentSerializer extends JsonSerializer<Payment> {

    private NameTransformer transformer;

    public UnwrappingPaymentSerializer(NameTransformer transformer) {
        this.transformer = transformer;
    }

    @Override
    public void serialize(Payment value, JsonGenerator generator, SerializerProvider provider) throws IOException {
        // some logics
    }

    @Override
    public boolean isUnwrappingSerializer() {
        return true;
    }
}

因此,您只有一个用于序列化和解包的序列化程序。 有关详细信息,请参阅:https://michael-simons.github.io/simple-meetup/unwrapping-custom-jackson-serializer

如果解决方案不适用请告诉我,我会根据项目要求尝试提出其他方法。