2017-02-09 10 views
3

Есть ли аннотации Джексона, которые позволят десериализовать массив в определенные поля моего POJO? Я легко могу сделать это с помощью специального десериализатора, но я надеялся, что это будет сделано в соответствии с классом.Jackson deserialize элементы массива в определенные поля

Например, у меня есть следующий JSON, возвращающийся из Elasticsearch.

{ 
    "_index": "twitter", 
    "_type": "tweet", 
    "_id": "AVodOsgk0etILSbJamY-", 
    "_score": null, 
    "_source": { 
     "tweetText": "I'm at Residencial Nova Alegria https:\/\/t.co\/4TyK8PAWzB", 
     "placeCountry": "Brasil", 
     "screenName": "wildelson", 
     "cleanedText": "I'm at Residencial Nova Alegria https:\/\/t.co\/4TyK8PAWzB", 
     "resolvedUrls": [ 
     "https:\/\/www.swarmapp.com\/c\/gfULJdQ6umw" 
     ], 
     "tweetId": "829272906291085314", 
     "tweetDate": 1486549042000 
    }, 
    "sort": [ 
     1486549042000, 
     "tweet#AVodOsgk0etILSbJamY-" 
    ] 
    } 

Мой POJO следующим образом:

import com.fasterxml.jackson.annotation.JsonInclude; 
import com.fasterxml.jackson.annotation.JsonProperty; 
import com.fasterxml.jackson.annotation.JsonPropertyOrder; 
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 
import lombok.Data; 

@Data 
@JsonInclude(JsonInclude.Include.NON_NULL) 
@JsonPropertyOrder(value = { 
    "enrichedStatus", 
    "sortValue", 
    "uid" 
}) 
public class TweetHit { 
    private final EnrichedStatus enrichedStatus; 
    private final Long sortValue; 
    private final String uid; 

    public TweetHit(EnrichedStatus enrichedStatus, Long sortValue, String uid) { 
     this.enrichedStatus = enrichedStatus; 
     this.sortValue = sortValue; 
     this.uid = uid; 
    } 

Я хочу «сортировки» массив, который всегда будет иметь длинный в массив [0] и строка в массиве [1], чтобы быть десериализован следующим образом:

Long sortValue = sort[0] 
String uid = sort[1] 

Я нашел еще один вопрос, где единственный ответ был обычай десериализации, который я хотел бы избежать, если я могу. Jackson: Deserialize JSON-Array in different attributes of an object

Я подумал, что, возможно, я могу использовать @JsonProperty("sort") с @JsonFormat(shape = ARRAY), но я не вижу, чтобы указать конкретную ячейку для десериализации в каждое поле.

Обратите внимание, что это неизменный объект, и поэтому мне, вероятно, понадобится решение для работы в режиме реального времени с конструктором, хотя, возможно, я могу удалить final, добавить пустой конструктор, поместить аннотации на уровне поля и использовать Lombok to отключить сеттеры, если Джексон может установить прямо в поля?

ответ

1

Вы можете подойти к этому с помощью аннотаций @JsonCreator и @JsonProperty и пользовательского конструктора. Так как я не знаю, что class EnrichedStatus выглядит как я упростил ваш пример только с sort массивом:

import java.io.IOException; 
import com.fasterxml.jackson.annotation.JsonCreator; 
import com.fasterxml.jackson.annotation.JsonProperty; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import lombok.Data; 

@Data 
class TweetHit { 
    private final Long sortValue; 
    private final String uid; 

    @JsonCreator 
    public TweetHit(@JsonProperty("sort") String[] sort) { 
     this.sortValue = Long.parseLong(sort[0]); 
     this.uid = sort[1]; 
    } 
} 

public class StackOverflow { 
    public static void main(String[] args) throws IOException { 
     String json = "{ \"sort\": [\n" + 
       "  1486549042000,\n" + 
       "  \"tweet#AVodOsgk0etILSbJamY-\"\n" + 
       " ]\n" + 
       " }"; 

     ObjectMapper objectMapper = new ObjectMapper(); 
     TweetHit tweetHit = objectMapper.readValue(json, TweetHit.class); 
    } 
} 

Это сохраняет неизменность TweetHit класса и избегает пользовательской десериализации.

Я не вижу способа сделать это с помощью @JsonFormat(shape = ARRAY), который служит для другой цели. Даже если бы это было возможно, я сомневаюсь, что это будет проще, чем конструктор, который принимает массив и назначает его содержимое полям.

Также проверьте this answer, если вы также хотели бы избежать @JsonCreator, @JsonProperty аннотации.

+0

Вау, я не могу поверить, что не видел этого. Я получил туннель с двумя полями, таким образом, 2 параметра. Это сработало. Благодаря! – Brooks