Reputation: 1399
I have this class:
@Data
public class DiscountDto {
@JsonProperty(required = true)
private DiscountType type;
@JsonProperty(required = true)
private double discountValue;
}
DiscountType is enum:
public enum DiscountType {
PERCENT, AMOUNT
}
I want to serialize the discountValue
to a specific value, depending on the Enum value. If enum have value PERCENT
, then discountValue must be serialize to percent_off
. If enum have value AMOUNT
then discountValue
must be serialize to amount_off
. How could I possibly do that?
Expected result:
If type == AMOUNT, I want discountValue name = amount_off
"discountDto": {
"amount_off": "11.0",
"type": "AMOUNT"
}
If type == PERCENT, I want discountValue name = percent_off
"discountDto": {
"percent_off": "11.0",
"type": "PERCENT"
}
Upvotes: 0
Views: 96
Reputation: 2109
Possible solutions:
1.Create a constructor with both DiscountType and discountValue and set directly the value of the percentOff or amountOff field:
@JsonInclude(Include.NON_NULL)
public class DiscountDto {
private DiscountType type;
@JsonProperty("percent_off")
private Double percentOff;
@JsonProperty("amount_off")
private Double amountOff;
public DiscountDto(DiscountType type, double discountValue){
this.type = type;
if(type.equals(DiscountType.PERCENT)){
this.percentOff = discountValue;
}else {
this.discountOff = discountValue;
}
}
//getters and setters
}
2.Use a custom JSON serializer:
public class DiscountDtoSerializer extends StdSerializer<DiscountDto> {
public DiscountDtoSerializer() {
this(null);
}
public DiscountDtoSerializer(Class<DiscountDto> t) {
super(t);
}
@Override
public void serialize(DiscountDto value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeNumberField("type", value.getDiscountType());
if(value.getDiscountType().equals(DiscountType.PERCENT)){
jgen.writeStringField("percent_off", value.getDiscountValue());
}else{
jgen.writeStringField("amount_off", value.getDiscountValue());
}
jgen.writeEndObject();
}
}
and your ObjectMapper should have this new serializer:
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(DiscountDto.class, new DiscountDtoSerializer());
mapper.registerModule(module);
Upvotes: 1
Reputation: 9786
This is a typical example of how not to do polymorphism. Don't get me wrong, I am not crticizing you, this has happend to most of us. This is a sort of inner-state polymorphism, that is, depending on the value of some property (type
even the name says it, right?) some other property gets a different meaning.
To solve the problem correctly, you should move the poperty type, at the level of the class, having a class for each type. You can start by having an abstract, uninstantiable type, and your specific types will derive from it.
You can find some sample implementation here, for technical reference.
Upvotes: 0