一つの選択肢は、あなたのResource
種類のカスタムデシリアライザを作成することです。その中でJSONメッセージ内のヒントを使用して、Resource
の型を決定します。
は、私はあなたのJSONメッセージがどのように見えるかわからないんだけど、解決策は次のようになります...
public class ResourceDeserializer implements JsonDeserializer<Resource> {
@Override
public Resource deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
final JsonObject root = json.getAsJsonObject();
final Resource resource;
if("wood".equalsIgnoreCase(root.get("type"))) {
resource = new WoodResource();
} else {
resource = new StoneResource();
}
return resource;
}
}
UPDATED
abstract class Resource {
protected String id;
protected Integer quantity;
}
class Wood extends Resource {}
class Stone extends Resource {}
class ResourceMap {
protected Map<String,Resource> resources;
ResourceMap() {
this.resources = new HashMap<>();
}
}
class ResourceMapDeserializer implements JsonDeserializer<ResourceMap> {
@Override
public ResourceMap deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
final JsonObject root = json.getAsJsonObject();
final ResourceMap instance = new ResourceMap();
instance.resources.put("Wood", parse(root, "Wood"));
instance.resources.put("Stone", parse(root, "Stone"));
return instance;
}
private Resource parse(JsonObject root, String fieldName) {
final JsonElement field = root.get(fieldName);
if(field != null) {
final Resource resource;
if("Wood".equalsIgnoreCase(fieldName)) {
resource = new Wood();
} else {
resource = new Stone();
}
resource.quantity = field.getAsJsonObject().get("quantity").getAsInt();
return resource;
} else {
return null;
}
}
}
簡単な検証を
@RunWith(MockitoJUnitRunner.class)
public class ResourceDeserializerTest {
@Mock private JsonDeserializationContext mockContext;
private Gson gson;
@Before
public void setUp() {
gson = new GsonBuilder()
.registerTypeAdapter(ResourceMap.class, new ResourceMapDeserializer())
.setPrettyPrinting()
.create();
}
@Test
public void deserializes_resource_map() {
final JsonObject woodJson = new JsonObject();
woodJson.addProperty("quantity", 4);
final JsonObject stoneJson = new JsonObject();
stoneJson.addProperty("quantity", 2);
final JsonObject mapJson = new JsonObject();
mapJson.add("Wood", woodJson);
mapJson.add("Stone", stoneJson);
final ResourceMap deserialized = gson.fromJson(mapJson, ResourceMap.class);
assertThat(deserialized.resources.get("Wood").getClass()).isEqualTo(Wood.class);
assertThat(deserialized.resources.get("Stone").getClass()).isEqualTo(Stone.class);
}
}
出典
2017-06-20 01:57:13
hsl
これは良い応答ですが、私は問題は、私はjson desリソースセットではなく、リソースセットでのエイリアライザ。私はこのjson文字列を逆シリアル化したいとします: '{" resourcesMap ":{" Wood ":{" quantity ":4}" Stone ":{" quantity ":2}}}' –
1レベルアップ "し、' Map '自身を逆直列化します。私は私の答えにアップデートを加えて、私が何を言っているかを実証しました。 –
hsl