2017-10-23 1 views
1

Ich möchte eine Eigenschaft zu einer anderen Eigenschaft deserialisieren, wenn es null ist.Jackson: Deserialize Eigenschaft zu einer anderen Eigenschaft, wenn es Null ist

Sagen wir, ich habe eine Klasse:

public class User { 
    private String login; 
    private String nickname; 
    // getters, setters 
} 

Jedes Mal nickname als null kommt würde ich login als Standardwert zurückkommen.

F: Gibt es eine allgemeine Möglichkeit, dies mit Jackson Deserializers zu erreichen?

Hinweis: Es gibt eine Zwangs vorwärts Weg, Getter wie dies das Problem lösen:

public String getNickname() { 
    return nickname == null ? login : nickname; 
} 

Aber es ist nicht elegant, und ich will keine Logik in meine DTO Objekte setzen .

Antwort

0

Sie können benutzerdefinierte die Serialisierung

public class CustomFooSerialize extends JsonSerializer<Foo> { 

    @Override 
    public void serialize(Foo foo, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { 

     if (foo.getNickname() == null) { 
      jsonGenerator.writeStartObject(); 
      jsonGenerator.writeStringField("nickname", foo.getLogin()); 
      jsonGenerator.writeEndObject(); 
     } 
    } 
} 

den Serializer direkt auf die Klasse registrieren

@JsonSerialize(using = CustomFooSerialize.class) 
public class Foo 
+0

Vielen Dank für die Antwort. Dies wird nicht funktionieren, da dieser Code in ein json serialisiert wird, aber ich muss es zu Java-Objekt deserialisieren. Aber ich habe die Idee verstanden. Leider ist es für mich nicht anwendbar, ich hätte gerne eine allgemeine Lösung. –

+0

@OleksandrShpota In der gleichen Weise können Sie benutzerdefinierte die Deserialisierung –

0

Während der Deserialisierung jackson Setter der Klasse aufruft. Also, würde ich versuchen:

public void setNickname(String nickname) { 
    this.nickname == nickname; 
    if (nickname != null) { 
     login = nickname; 
    } 
} 

Die Eigenschaft Login benötigt wahrscheinlich @ JsonIgnore in diesem Fall. Wie auch immer, dieser Code ist verwirrend, weil Setter einen Nebeneffekt hat.

Rückkehr zum Deserializer. In diesem Fall müssen Sie einen benutzerdefinierten Deserializer schreiben:

import com.fasterxml.jackson.core.JsonParser; 
import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.core.ObjectCodec; 
import com.fasterxml.jackson.databind.DeserializationContext; 
import com.fasterxml.jackson.databind.JsonDeserializer; 
import com.fasterxml.jackson.databind.JsonNode; 
import java.io.IOException; 

public class UserDeserializer extends JsonDeserializer<User> { 

    @Override 
    public User deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 

     ObjectCodec oc = jp.getCodec(); 

     JsonNode node = oc.readTree(jp); 

     //final Long id = node.get("id").asLong(); 
     final String nickname = node.get("nickname").asText(); 
     final String login = null; 
     if (nickname != null) { 
      login = nickname; 
     } 
     User user = new User(); 
     user.setNickname(nickname); 
     user.setLogin(login); 
     return user; 
    } 
} 

Entschuldigung für möglicherweise falsche Einrückung.

+0

Vielen Dank für die Antwort, aber es ist keine allgemeine Lösung. Ich muss für jeden DTO so etwas schreiben. –

Verwandte Themen