@JsonUnwrapped does not work with a custom Serializer (StdSerializer<T>)
See original GitHub issueI need to write a custom Serializer for one of my entities “Payment” and I have to implement it by extending 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
}
}
Since I use Spring, I register this Serializer so Spring could identify it:
@Bean
public Jackson2ObjectMapperBuilder serializersObjectMapperBuilder() {
SimpleModule module = new SimpleModule();
module.addSerializer(Payment.class, applicationContext.getBean(PaymentSerializer.class));
return new Jackson2ObjectMapperBuilder().modules(module);
}
Now I have a controller that returns data back to the client and it uses this Serializer without any problem:
@RestController
@RequestMapping("/payment")
class PaymentController {
@GetMapping
public List<Payment> getAll() {
return Arrays.asList(new Payment());
}
}
Since now, my Serializer works fine and everything is good.
The problem is with another entity “Order” which has Payment as a property with @JsonUnwrapped:
class Order {
@JsonUnwrapped
private Payment payment;
}
I need to unwrap the Payment inside the Order and I want to use the same PaymentSerializer but the problem is when I use this custom Serializer, the @JsonUnwrapped annotation will be ignored and the output will be something like this:
{
"payment": {
.....
}
}
As I mentioned, I want to eliminate the “payment” field and unwrap it.
I know that for emulating @JsonUnwrapped for a custom Serializer I need to extend UnwrappingBeanSerializer class, but as I mentioned at first, I need the standard Serializer too.
Changing my entity models is not an option for me.
Is there any way to accomplish this?
I use Spring Boot 2.1.3.RELEASE which I believe uses Jackson 2.9
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (4 by maintainers)
Top Related StackOverflow Question
In case someone needs help understanding how to implement a serializer supporting unwrapping, here’s what you need to do (code shown in Kotlin syntax):
EDIT: at least this worked for my use case… not sure if I should’ve used the
NameTransformersomehow but it did not seem to be required.Only standard POJOs handled with
BeanSerializer/BeanDeserializersupport use of@JsonUnwrappedwithout extra work. If you want it to work for custom types (ones with custom (de)serializers, you will need to do more work. Custom (de)serializers typically have to add explicit support for any and all annotations.For serializers, you need to implement
JsonSerializer.unwrappingSerializer()and for deserializersJsonDeserializer.unwrappingDeserializer(): these are factory methods that create instances that will handle all the complexities of dealing with changing structure. I would not recommend extendingUnwrappingBeanSerializer; it is an internal class and unlikely to work for your case.