@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 GitHub Comments
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
NameTransformer
somehow but it did not seem to be required.Only standard POJOs handled with
BeanSerializer
/BeanDeserializer
support use of@JsonUnwrapped
without 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.