itsource

잭슨:열거형 값을 정수로 직렬화 및 직렬화 해제

mycopycode 2023. 2. 26. 09:45
반응형

잭슨:열거형 값을 정수로 직렬화 및 직렬화 해제

다음 열거 및 클래스를 고려합니다.

public enum State {
    OFF,
    ON,
    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, State.OFF);
    ObjectMapper mapper = new ObjectMapper();
    String machineAsJsonString = mapper.writeValueAsString(m);
    System.out.println(machineAsJsonString);
}

현재 이 메인 출력은 다음과 같습니다.

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

이 출력은 문자열 대신 좋지 않습니다."OFF"위해서state, 나는 그것이 되길 바란다.0의 순서값입니다.OFF일람표에서State.

따라서 실제로 얻을 수 있는 결과는 다음과 같습니다.

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

이런 식으로 행동할 수 있는 우아한 방법이 있을까요?

이 기능은, 다음의 항목을 지정해 주세요.JsonValue맵퍼

public enum State {
    OFF,
    ON,
    UNKNOWN;

    @JsonValue
    public int toValue() {
        return ordinal();
    }
}  

이것은, 다음의 Javadoc 에 기재되어 있듯이, 역직렬화에도 유효합니다.@JsonValue주석:

주의: Java Enum에 사용할 경우 주석 방식으로 반환되는 값은 직렬화하는 JSON 문자열뿐만 아니라 직렬화 해제되는 값으로 간주됩니다.Enum 값 집합은 일정하고 매핑을 정의할 수 있지만 일반적으로 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 {
       OFF,
       ON,
       UNKNOWN
}

또 다른 방법:

public enum State {

    @JsonProperty("0")
    OFF,

    @JsonProperty("1")
    ON,

    @JsonProperty("2")
    UNKNOWN
}

하지만 이렇게 하면{"state" : "1"}대신{"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(){...}
}

열거의 서수를 인쇄하려면 생성자를 변경하여 다음 명령을 수락할 수 있습니다.int대신State그리고 나서 전화할 때Machine다음과 같은 방법으로 구성할 수 있습니다.

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

전달된 상태의 열거 서수 값을 가져오고 다음을 인쇄합니다.

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

정수 enum의 경우 kotlin에서 이 방법이 적합합니다.자바에서도.서수를 사용하지 않으려면.

enum class State(@get:JsonValue val state: Int) {
          OFF(0),
          ON(1),
          UNKNOWN(-1)
}

생성된 바이트 코드는 다음과 같습니다.

@JsonValue
public final int getState() {
  return this.state;

}

언급URL : https://stackoverflow.com/questions/37833557/jackson-serialize-and-deserialize-enum-values-as-integers

반응형