Betrachten Sie die folgende Enumeration und Klasse:
public enum State {
ON,
OFF,
UNKNOWN
}
public class Machine {
String name;
int numCores;
State state;
public Machine(String name, int numCores, State state) {
this.name = name;
this.numCores = numCores;
this.state = state;
}
}
Und betrachten Sie die folgende Hauptfunktion:
public static void main(String args[]) {
Machine m = new Machine("Machine 1", 8, OFF);
ObjectMapper mapper = new ObjectMapper();
String machineAsJsonString = mapper.writeValueAsString(m);
System.out.println(machineAsJsonString);
}
Derzeit ist die Ausgabe dieses Hauptteils:
{"name" : "Machine 1", "numCores" : 8, "state" : "OFF"}
Diese Ausgabe ist nicht gut für mich, da ich anstelle der Zeichenfolge "OFF"
für state
1
verwenden möchte. Dies ist der Ordinalwert von OFF
im Enum State
.
Das eigentliche Ergebnis, das ich erhalten möchte, ist:
{"name" : "Machine 1", "numCores" : 8, "state" : 1}
Gibt es eine elegante Möglichkeit, sich so zu verhalten?
Es sollte funktionieren, indem Sie JsonValue
mapper angeben.
public enum State {
ON,
OFF,
UNKNOWN;
@JsonValue
public int toValue() {
return ordinal();
}
}
Dies funktioniert auch für die Deserialisierung, wie in Javadoc der @JsonValue
-Anmerkung angegeben:
HINWEIS: Bei Verwendung für Java-Enums ist der Wert .__ eine weitere Funktion. von annotierter Methode zurückgegeben wird auch als Wert für .__ betrachtet. Deserialize, nicht nur als JSON-String, als Serialisierung. Das ist möglich, da die Menge der Aufzählungswerte konstant ist und es möglich ist, Definieren Sie das Mapping, kann jedoch nicht generell für POJO-Typen ausgeführt werden. wie Dies wird also nicht zur POJO-Deserialisierung verwendet
Sie können die Einstellung verwenden
objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_INDEX);
Siehe https://github.com/FasterXML/jackson-databind/blob/master/src/test/Java/com/fasterxml/jackson/databind/ser/TestEnumSerialization.Java für vollständige Testfälle
Vielen Dank an https://righele.it/2016/01/30/jackson-deserialization-von-json-nach-Java-enums/
Sie können auf diese Weise verwenden
import com.fasterxml.jackson.annotation.JsonFormat;
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
public enum State {
ON,
OFF,
UNKNOWN
}
Wenn Sie die Ordnungszahl der Aufzählung drucken möchten, können Sie Ihren Konstruktor so ändern, dass er ein int
anstelle von State
akzeptiert. Anschließend können Sie ihn in Ihrem Aufruf an Machine
strukturieren folgenden Weg:
Machine m = new Machine("Machine 1", 8, State.OFF.ordinal());
Dadurch wird der Ordnungszahlwert des übergebenen Zustands abgerufen und Folgendes ausgegeben
{name='Machine 1', numCores=8, state=1}
Zur Vervollständigung poste ich einen anderen Weg: benutzerdefinierte Serialisierer:
public class StateSerializer extends JsonSerializer<State> {
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(){...}
}
Noch ein anderer Weg:
public enum State {
@JsonProperty("0")
ON,
@JsonProperty("1")
OFF,
@JsonProperty("2")
UNKNOWN
}
Dies erzeugt jedoch {"state" : "1"}
anstelle von {"state" : 1}
(Zeichenfolge, nicht numerisch). In den meisten Fällen ist es OK