Mridang Agarwalla:
私はこれに似ているBeanを持っています:
public class Product {
public String id;
public String vendor;
public Set<Image> images;
}
public class Image {
public String originalSrc;
}
私はこれに似ている私のJSONをデシリアライズしようとしています:
{
"id": "gid:\/\/mysite\/Product\/1853361520730",
"vendor": "gadgetdown",
"images": {
"edges": [
{
"node": {
"originalSrc": "https:\/\/cdn.something.com"
}
},
{
"node": {
"originalSrc": "https:\/\/cdn.something.com"
}
}
]
}
私はそれぞれのように、オブジェクトをデシリアライズすることができないんだimage
オブジェクトがでラップされnode
たオブジェクトと総称してedges
オブジェクト。
編集:明確にするために、私は豆を使用して経由して、これを達成するためにしたくないと、この例では、簡素化され、JSONペイロード内のすべての配列項目は、この中に包まれているedges
とnode
表現。
マイケルZiober:
すべてのリストは以下のような構造を持っている場合:
{
"images": {
"edges": [
{
"node": {
"entry": "entry-value"
}
}
]
}
}
各リストであるJSON Object
とのedges
性質と、アレイ内の各要素は、によってラップされるJSON Object
とnode
プロパティ。このような構造のために、私たちは、からのものと同様の一般的なデシリアライザを書くことができます1つのより高いレベルのリストにオブジェクトの内部リストをデシリアライズ-ジャクソン質問。
例のSet
デシリアライザ:
class InnerSetDeserializer extends JsonDeserializer<Set> implements ContextualDeserializer {
private final JavaType propertyType;
public InnerSetDeserializer() {
this(null);
}
public InnerSetDeserializer(JavaType propertyType) {
this.propertyType = propertyType;
}
@Override
public Set deserialize(JsonParser p, DeserializationContext context) throws IOException {
p.nextToken(); // SKIP START_OBJECT
p.nextToken(); // SKIP any FIELD_NAME
CollectionType collectionType = getCollectionType(context);
List<Map<String, Object>> list = context.readValue(p, collectionType);
p.nextToken(); // SKIP END_OBJECT
return list.stream().map(Map::values).flatMap(Collection::stream).collect(Collectors.toSet());
}
private CollectionType getCollectionType(DeserializationContext context) {
TypeFactory typeFactory = context.getTypeFactory();
MapType mapType =
typeFactory.constructMapType(
Map.class, String.class, propertyType.getContentType().getRawClass());
return typeFactory.constructCollectionType(List.class, mapType);
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext context, BeanProperty property) {
return new InnerSetDeserializer(property.getType());
}
}
我々は使用することができ、以下の通りです:
class Product {
private String id;
private String vendor;
@JsonDeserialize(using = InnerSetDeserializer.class)
private Set<Image> images;
// getters, setters
}
例のアプリ:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.databind.type.MapType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class JsonApp {
public static void main(String[] args) throws IOException {
File jsonFile = new File("./resources/test.json");
ObjectMapper mapper = new ObjectMapper();
Product product = mapper.readValue(jsonFile, Product.class);
System.out.println(product);
}
}
上記のコードを印刷:
Product{id='gid://mysite/Product/1853361520730', vendor='gadgetdown', images=[Image{originalSrc='https://cdn.something.com'}, Image{originalSrc='https://cdn.something.com'}]}