Jackson: Sérialiser et désérialiser les valeurs enum sous forme d’entiers

Considérez l’énumération et la classe suivantes:

public enum State { ON, OFF, UNKNOWN } public class Machine { Ssortingng name; int numCores; State state; public Machine(Ssortingng name, int numCores, State state) { this.name = name; this.numCores = numCores; this.state = state; } } 

Et considérons la fonction principale suivante:

 public static void main(Ssortingng args[]) { Machine m = new Machine("Machine 1", 8, OFF); ObjectMapper mapper = new ObjectMapper(); Ssortingng machineAsJsonSsortingng = mapper.writeValueAsSsortingng(m); System.out.println(machineAsJsonSsortingng); } 

Actuellement, le résultat de ce principal est:

 {"name" : "Machine 1", "numCores" : 8, "state" : "OFF"} 

Cette sortie n’est pas bonne pour moi, car au lieu de la chaîne "OFF" pour state , j’aimerais qu’elle soit égale à 1 , ce qui correspond à la valeur ordinale de OFF dans l’ State enum.

Donc, le résultat réel que je veux obtenir est:

 {"name" : "Machine 1", "numCores" : 8, "state" : 1} 

Y a-t-il une manière élégante de le faire se comporter de cette façon?

Cela devrait fonctionner en spécifiant le mappeur JsonValue .

 public enum State { ON, OFF, UNKNOWN; @JsonValue public int toValue() { return ordinal(); } } 

Ceci fonctionne également pour la désérialisation, comme indiqué dans Javadoc de l’annotation @JsonValue :

REMARQUE: lors de l’utilisation d’énums Java, une fonctionnalité supplémentaire est que la valeur renvoyée par la méthode annotée est également considérée comme la valeur à partir de laquelle la désérialisation est effectuée, et pas uniquement la chaîne JSON à sérialiser. Cela est possible car l’ensemble des valeurs Enum est constant et qu’il est possible de définir un mappage, mais ne peut généralement pas être effectué pour les types POJO; en tant que tel, ceci n’est pas utilisé pour la désérialisation de POJO

Vous pouvez utiliser le réglage

 objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_INDEX); 

Voir https://github.com/FasterXML/jackson-databind/blob/master/src/test/java/com/fasterxml/jackson/databind/ser/TestEnumSerialization.java pour des tests complets.

Merci de laisser un pourboire à https://righele.it/2016/01/30/jackson-deserialization-from-json-to-java-enums/

Si vous voulez imprimer l’ordinal de l’énum, ​​vous pouvez changer votre constructeur pour accepter un int au lieu de State , puis dans votre appel à Machine vous pouvez le structurer de la manière suivante:

Machine m = new Machine("Machine 1", 8, State.OFF.ordinal());

Ceci obtiendra la valeur ordinale d’énumération de l’état passé et affichera le texte suivant.

{name='Machine 1', numCores=8, state=1}

Pour terminer, je poste une autre manière: sérialiseur personnalisé:

 public class StateSerializer extends JsonSerializer { public void serialize(State value, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException { generator.writeStartObject(); generator.writeFieldName("id"); generator.writeNumber(value.getId()); generator.writeEndObject(); } } @JsonSerialize(using = StateSerializer.class) public enum State { ... public int getId(){...} } 

Encore une autre manière:

 public enum State { @JsonProperty("0") ON, @JsonProperty("1") OFF, @JsonProperty("2") UNKNOWN } 

Cependant, cela produira {"state" : "1"} au lieu de {"state" : 1} (chaîne, pas numérique). Dans la plupart des cas, ça va