次の列挙型とクラスを検討してください。
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;
}
}
そして、次の主な機能を検討してください。
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);
}
現在、このメインの出力は次のとおりです。
{"name" : "Machine 1", "numCores" : 8, "state" : "OFF"}
この出力は、state
の文字列"OFF"
の代わりに、_1
にしたいと思います。これは、enum OFF
のState
の序数値です。
だから私が取得したい実際の結果は:
{"name" : "Machine 1", "numCores" : 8, "state" : 1}
このように動作させるエレガントな方法はありますか?
JsonValue
マッパーを指定することで機能するはずです。
public enum State {
ON,
OFF,
UNKNOWN;
@JsonValue
public int toValue() {
return ordinal();
}
}
@JsonValue
アノテーションのJavadocに記載されているように、これは逆シリアル化でも機能します。
注:Java列挙型を使用する場合、注釈付きメソッドによって返される値は、シリアライズするJSON文字列だけでなく、デシリアライズする値でもあると見なされるという追加機能があります。列挙値のセットは定数であり、マッピングを定義することは可能ですが、一般にPOJO型に対しては実行できません;そのため、これはPOJOデシリアライゼーションには使用されません
設定を使用できます
objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_INDEX);
完全なテストケースについては、 https://github.com/FasterXML/jackson-databind/blob/master/src/test/Java/com/fasterxml/jackson/databind/ser/TestEnumSerialization.Java を参照してください
https://righele.it/2016/01/30/jackson-deserialization-from-json-to-Java-enums/ のヒントに感謝します
このように使用できます
import com.fasterxml.jackson.annotation.JsonFormat;
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
public enum State {
ON,
OFF,
UNKNOWN
}
列挙型の序数を出力する場合は、int
の代わりにState
を受け入れるようにコンストラクターを変更し、Machine
の呼び出しで構造化できます。次の方法:
Machine m = new Machine("Machine 1", 8, State.OFF.ordinal());
これは、渡された状態の列挙値を取得し、次を出力します
{name='Machine 1', numCores=8, state=1}
完了のために、別の方法を投稿します:カスタムシリアライザー:
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(){...}
}
さらに別の方法:
public enum State {
@JsonProperty("0")
ON,
@JsonProperty("1")
OFF,
@JsonProperty("2")
UNKNOWN
}
ただし、これにより{"state" : "1"}
の代わりに {"state" : 1}
(数値ではなく文字列)。ほとんどの場合、大丈夫です