We need convert external name to enum sometimes, jackson supports deserialize enum base on @JsonProperty
import com.fasterxml.jackson.annotation.JsonProperty;
public enum PublicKeyCredentialType {
@JsonProperty("public-key")
public_key;
}
It would be great if spring respect @JsonProperty, here is my raw improvement for built-inStringToEnumConverterFactory
@Override
public T convert(String source) {
if (source.isEmpty()) {
// It's an empty enum identifier: reset the enum value to null.
return null;
}
try {
return (T) Enum.valueOf(this.enumType, source.trim());
} catch (IllegalArgumentException e) {
for (Field f : this.enumType.getFields()) {
if (f.getType() == this.enumType) {
JsonProperty jp = f.getAnnotation(JsonProperty.class);
if (jp != null && source.equals(jp.value())) {
try {
return (T) f.get(null);
} catch (IllegalArgumentException | IllegalAccessException e1) {
// never happens
}
}
}
}
throw e;
}
}
Comment From: knmueller
Any update on if this will get prioritized? This is something I ran into which took a few hours of debug to figure out that it wasn't actually supported. Would be nice to have this happen automatically. I was able to work around this for now by adding a custom validator to my request POJO, which uses an object mapper to try and readValue
into the enum.
public class MyEventValidator implements ConstraintValidator<MyEvent, String> {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
try {
mapper.readValue("\"" + value + "\"", MyEvent.class);
} catch (JsonProcessingException e) {
return false;
}
return true;
}
}
@Target({ FIELD })
@Retention(RUNTIME)
@Constraint(validatedBy = MyEventValidator.class)
@Documented
public @interface MyEvent {
String message() default "Invalid event in request";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
public class MyEventRequest {
@MyEvent
private String event;
}
This does only get me the validation of the request field. There is more boiler plate code to then convert the String to the enum.
Comment From: sdeleuze
Taking in account a Jackson annotation at org.springframework.core.convert
level does not look like something natural to me. It would be too much JSON/Jackson specific, would be a breaking change for some current valid use cases, and would open the door to various follow-up issues to handle this kind of concern in a consistent way. As a consequence, I decline this issue.