diff --git a/src/main/java/it/aboutbits/springboot/toolbox/autoconfiguration/web/CustomTypeConfiguration.java b/src/main/java/it/aboutbits/springboot/toolbox/autoconfiguration/web/CustomTypeConfiguration.java index 309d363..323609c 100644 --- a/src/main/java/it/aboutbits/springboot/toolbox/autoconfiguration/web/CustomTypeConfiguration.java +++ b/src/main/java/it/aboutbits/springboot/toolbox/autoconfiguration/web/CustomTypeConfiguration.java @@ -2,8 +2,11 @@ import it.aboutbits.springboot.toolbox.jackson.CustomTypeDeserializer; import it.aboutbits.springboot.toolbox.jackson.CustomTypeSerializer; +import it.aboutbits.springboot.toolbox.jackson.EntityIdDeserializer; import it.aboutbits.springboot.toolbox.type.CustomType; +import it.aboutbits.springboot.toolbox.type.identity.EntityId; import it.aboutbits.springboot.toolbox.web.CustomTypePropertyEditor; +import it.aboutbits.springboot.toolbox.web.EntityIdPropertyEditor; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -29,6 +32,7 @@ public void initBinder(WebDataBinder binder) { for (var clazz : types) { binder.registerCustomEditor(clazz, new CustomTypePropertyEditor<>(clazz)); } + binder.registerCustomEditor(EntityId.class, new EntityIdPropertyEditor()); } } @@ -41,8 +45,11 @@ public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer(CustomTypeScanner co .toList() .toArray(new CustomTypeDeserializer[types.size()]); + return builder -> builder .serializers(new CustomTypeSerializer()) - .deserializers(deserializers); + .deserializers(deserializers) + .deserializerByType(EntityId.class, new EntityIdDeserializer()); } + } diff --git a/src/main/java/it/aboutbits/springboot/toolbox/jackson/EntityIdDeserializer.java b/src/main/java/it/aboutbits/springboot/toolbox/jackson/EntityIdDeserializer.java new file mode 100644 index 0000000..14113f6 --- /dev/null +++ b/src/main/java/it/aboutbits/springboot/toolbox/jackson/EntityIdDeserializer.java @@ -0,0 +1,50 @@ +package it.aboutbits.springboot.toolbox.jackson; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import it.aboutbits.springboot.toolbox.type.identity.EntityId; + +import java.io.IOException; + +public class EntityIdDeserializer extends JsonDeserializer> { + /* + This is needed because EntityId is just the interface. Jackson does not know what implementation to take. + So we use this generic implementation. + */ + @Override + public EntityId deserialize( + JsonParser jsonParser, + DeserializationContext deserializationContext + ) throws IOException { + // We need to do this because due to type erasure we don't actually know the wrapped type. So we try a number first and fallback to a string. + try { + var theValue = jsonParser.getLongValue(); + return new EntityId() { + @Override + public Long value() { + return theValue; + } + + @Override + public String toString() { + return String.valueOf(value()); + } + }; + } catch (JsonParseException e) { + var theValue = jsonParser.getValueAsString(); + return new EntityId() { + @Override + public String value() { + return theValue; + } + + @Override + public String toString() { + return theValue; + } + }; + } + } +} diff --git a/src/main/java/it/aboutbits/springboot/toolbox/web/EntityIdPropertyEditor.java b/src/main/java/it/aboutbits/springboot/toolbox/web/EntityIdPropertyEditor.java new file mode 100644 index 0000000..8629715 --- /dev/null +++ b/src/main/java/it/aboutbits/springboot/toolbox/web/EntityIdPropertyEditor.java @@ -0,0 +1,52 @@ +package it.aboutbits.springboot.toolbox.web; + +import it.aboutbits.springboot.toolbox.type.identity.EntityId; +import org.springframework.lang.Nullable; + +import java.beans.PropertyEditorSupport; + +public final class EntityIdPropertyEditor extends PropertyEditorSupport { + @SuppressWarnings("unchecked") + @Override + @Nullable + public String getAsText() { + var value = (EntityId) getValue(); + + return value == null ? null : value.toString(); + } + + @Override + public void setAsText(String text) throws IllegalArgumentException { + EntityId value = null; + try { + var theValue = Long.parseLong(text); + value = new EntityId() { + @Override + public Long value() { + return theValue; + } + + @Override + public String toString() { + return String.valueOf(value()); + } + }; + } catch (NumberFormatException e) { + value = new EntityId() { + @Override + public String value() { + return text; + } + + @Override + public String toString() { + return value(); + } + }; + } + + setValue( + value + ); + } +}