问题描述
我需要为我的实体“Payment”之一编写自定义序列化程序,我必须通过扩展 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);
}
现在我有一个控制器将数据返回给客户端,它使用这个序列化程序没有任何问题:
@RestController
@RequestMapping("/payment")
class PaymentController {
@GetMapping
public List<Payment> getAll() {
return Arrays.asList(new Payment());
}
}
从现在开始,我的序列化程序运行良好,一切正常。
问题出在另一个实体“Order”上,该实体将 Payment 作为属性使用 @JsonUnwrapped
:
class Order {
@JsonUnwrapped
private Payment payment;
}
我需要解开 Payment
中的 Order
并且我想使用相同的 PaymentSerializer 但问题是当我使用这个自定义序列化程序时,{{1 }} 注释将被忽略,输出将是这样的:
@JsonUnwrapped
正如我所提到的,我想消除“付款”字段并将其打开。
我知道要为自定义序列化程序模拟 {
"payment": {
.....
}
}
,我需要扩展 @JsonUnwrapped
类,但正如我最初提到的,我也需要标准序列化程序。
改变我的实体模型不是我的选择。
有没有办法做到这一点?
我使用 UnwrappingBeanSerializer
,我认为它使用了 Spring Boot 2.1.3.RELEASE
解决方法
我提出以下解决问题的方法:
我们可以在单个自定义序列化程序中组合两个 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,SerializerProvider provider) throws IOException {
// some logics
}
@Override
public boolean isUnwrappingSerializer() {
return true;
}
}
因此,您只有一个用于序列化和解包的序列化程序。 有关详细信息,请参阅:https://michael-simons.github.io/simple-meetup/unwrapping-custom-jackson-serializer
如果解决方案不适用,请告诉我,我会根据项目要求尝试提出其他方法。