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