使用@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
如果解决方案不适用请告诉我,我会根据项目要求尝试提出其他方法。
我需要为我的实体“付款”之一编写一个自定义序列化程序,我必须通过扩展 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
如果解决方案不适用请告诉我,我会根据项目要求尝试提出其他方法。