杰克逊将数组元素反序列化为特定字段
Jackson deserialize array elements into specific fields
是否有 Jackson 注释允许将数组反序列化为我的 POJO 的特定字段?我可以使用自定义反序列化器轻松完成此操作,但我希望通过 class 在线完成此操作。
例如,我有以下 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;
}
我想要 "sort" 数组,它在数组 [0] 中总是有一个 long,在数组[1] 中总是有一个 String,反序列化如下:
Long sortValue = sort[0]
String uid = sort[1]
我发现了另一个问题,其中唯一的答案是自定义反序列化器,如果可以的话我想避免使用。
我想也许我可以以某种方式将 @JsonProperty("sort")
与 @JsonFormat(shape = ARRAY)
一起使用,但无论如何我都看不到指定要反序列化到每个字段的特定单元格。
请注意,这是一个不可变对象,因此我可能需要解决方案与构造函数一起工作,但也许我可以删除 final,添加一个空构造函数,将注释放在字段级别并使用 Lombok如果 Jackson 可以直接设置到田间,禁用二传手?
您可以使用 @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 Whosebug {
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
class 的不变性并避免了自定义反序列化器。
我看不出有什么方法可以用 @JsonFormat(shape = ARRAY)
来实现不同的目的。即使有可能,我怀疑它会比采用数组并将其内容分配给字段的构造函数更简单。
如果您还想避免 @JsonCreator
、@JsonProperty
注释,请同时选中 this answer。
是否有 Jackson 注释允许将数组反序列化为我的 POJO 的特定字段?我可以使用自定义反序列化器轻松完成此操作,但我希望通过 class 在线完成此操作。
例如,我有以下 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;
}
我想要 "sort" 数组,它在数组 [0] 中总是有一个 long,在数组[1] 中总是有一个 String,反序列化如下:
Long sortValue = sort[0]
String uid = sort[1]
我发现了另一个问题,其中唯一的答案是自定义反序列化器,如果可以的话我想避免使用。
我想也许我可以以某种方式将 @JsonProperty("sort")
与 @JsonFormat(shape = ARRAY)
一起使用,但无论如何我都看不到指定要反序列化到每个字段的特定单元格。
请注意,这是一个不可变对象,因此我可能需要解决方案与构造函数一起工作,但也许我可以删除 final,添加一个空构造函数,将注释放在字段级别并使用 Lombok如果 Jackson 可以直接设置到田间,禁用二传手?
您可以使用 @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 Whosebug {
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
class 的不变性并避免了自定义反序列化器。
我看不出有什么方法可以用 @JsonFormat(shape = ARRAY)
来实现不同的目的。即使有可能,我怀疑它会比采用数组并将其内容分配给字段的构造函数更简单。
如果您还想避免 @JsonCreator
、@JsonProperty
注释,请同时选中 this answer。