Em fasterxml, depois de JSON desserialização, se enum é a primeira propriedade em classe, outros campos são nulos

David:

Em fasterxml, depois de JSON desserialização, se enum (com JsonFormat.Shape.OBJECT) é a primeira propriedade em classe, outros campos são nulos.

Por enum deve ser passada declarou propriedade na classe para desserializar outros campos corretamente?

Talvez isso poderia ser um bug no fasterxml?

Exemplo classe MyClass:

public class MyClass {

// >>>
// >>> element field is null after deserialization
// >>>
private MyEnum option; // first
private String element; // --> null

// >>> 
// >>> correctly deserialized if enum is last in order
// >>>
// private String element; // --> "elem"
// private MyEnum option; // last


public MyEnum getOption() {
    return option;
}

public void setOption(MyEnum option) {
    this.option = option;
}

public String getElement() {
    return element;
}

public void setElement(String element) {
    this.element = element;
}
} 

Exemplo enum MyEnum:

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum MyEnum {

FIRST;

@JsonProperty
public String getOption() {
    return name();
}

@JsonCreator
public static MyEnum forValue(String option) {
    return FIRST;
}
}

Exemplo principal classe de teste Main:

    public class Main {
public static void main(String[] args) throws IOException {
    ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    MyClass myClass = new MyClass();

    myClass.setElement("elem");
    myClass.setOption(MyEnum.FIRST);

    String serialized = mapper.writer().withDefaultPrettyPrinter().writeValueAsString(myClass);
    System.out.println(String.format("serialized - %s", serialized));

    MyClass deserialized = mapper.readValue(serialized, MyClass.class);

    String deserializedResult = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(deserialized);
    System.out.println(String.format("deserialized - %s", deserializedResult));
}
}

Saída mostrando campo é nullapós a desserialização:

serialized - {
  "option" : {
   "option" : "FIRST"
  },
  "element" : "elem"
}
deserialized - {
  "option" : {
    "option" : "FIRST"
  },
  "element" : null
}

Saída após a fixação fim (linhas descomentei em MyClass):

serialized - {
  "element" : "elem",
  "option" : {
    "option" : "FIRST"
  }
}
deserialized - {
  "element" : "elem",
  "option" : {
    "option" : "FIRST"
  }
}
Sotirios Delimanolis:

Eu não poderia dizer se é um bug, você pode depurar e passo através do código para entender como Jackson "falhar" neste cenário. O uso de FAIL_ON_UNKNOWN_PROPERTIESpeles do problema, que está usando Stringcomo o tipo de parâmetro do seu forValuemétodo de fábrica. Em suma, Jackson fica "preso" em atravessar as fichas do conteúdo JSON.

Para corrigi-lo corretamente, ou seja. Não confie em ordem, você tem um par de opções. Em primeiro lugar, livrar-se da JsonFormat.Shape.OBJECTforma para a serialização do tipo enum e seu correspondente @JsonCreator. O padrão de serialização / desserialização para um enum é usar seu nome de qualquer maneira.

Em segundo lugar, se você realmente quiser manter a forma do objeto, você precisa mudar o seu @JsonCreatormétodo para receber um ObjectNode, já que é o que o JSON contém, não um String. De lá, você pode executar a desserialização-se (supondo que você tem mais constantes enum)

@JsonCreator
public static MyEnum forValue(ObjectNode object) {
    return MyEnum.valueOf(object.get("option").asText());
}

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=217941&siteId=1
Recomendado
Clasificación