Closed Keelorath closed 3 years ago
Neked csak JsonDeserializer
kell, ugyanis ez az alkalmazás nem fog adatot JSON-ként kiírni, legalábbis egyelőre.
EntityBuilder
az kuka. Entity
osztályról JsonDeserialize
kuka.
Kell egy EntityDeserializer
, ami képes megállapítani, hogy a JSON Entity
-t vagy egy öröklő osztályt reprezentál.
Ez után pedig regisztrálni kell egy SimpleModule
-t az ObjectMapper
-ben, ami megadja Entity
osztályhoz a EntityDeserializer
osztályt, mint deserializer.
@tmRobi ez majd neked is érdekes lehet, ugyanis a GUI is fog olvasni JSON-t, így a te osztályodnak DI-vel kell átadni egy ObjectMapper
példányt, ami a fentiek alapján össze van rakva.
Ez a JsonDeserializer volt órán? Mert kb 3. pédával felvázolt dokumentációt olvasom róla és mindegyik máshogy csinálja.
JsonDeserializer
Jackson-ból jön.
public class EntityDeserializer extends JsonDeserializer<Entity> {
@Override
public Entity deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
var object = p.getCodec().<ObjectNode>readTree(p);
// ...
}
}
Valahol Main
-ben:
var deserialization = new SimpleModule();
deserialization.addDeserializer(Entity.class, new EntityDeserializer());
objectMapper.registerModule(deserialization);
Mindezt persze úgy, hogy Dependency Injection barátságos legyen a dolog.
Bástya, itt a deserialize függvényben visszatérési értéknél valami ilyesminek kéne lenni?
if(isHero(object)== true){
return Hero(
health,
attack,
defense,
cooldown,
name,
lore,
xpPerLevel,
dmgIncreacePerLevel,
hpIncreasePerLevel,
cooldownMultiplierPerLevel
);
} else {
return Entity(
health,
attack,
defense,
cooldown,
name,
lore
);
}
Érdemesebb lenne metódusokba belepakolni a típus specifikus kódot, és akkor tudod, hogy abban a metódusban csak azzal a típussal kell foglalkoznod:
return isHero(object) ? buildHero(object) : buildEntity(object);
private Hero buildHero(ObjectNode object) {
// csak Hero kód
}
private Entity buildEntity(ObjectNode object) {
// csak Entity kód
}
Esetleg a kód duplikáció elkerülése érdekében még azt lehet csinálni, hogy Entity
mindenképpen készül, és ha megvannak a Hero
mezői is, akkor az entity
példányt "kibelezve" csak hozzárakjuk azokat az extra mezőket a konstruktor meghívásánál.
Meg tudtam oldani, viszont sírt azért, hogy Herot nem tud returnölni. Megváltoztathatom a buildHero function-t de akkor hogy néz az már ki. Mert ugye maga a deserializer is Entity. ''' public Entity deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
var object = p.getCodec().<ObjectNode>readTree(p);
return isHero(object) ? buildHero(object) : buildEntity(object);
}
private boolean isHero(ObjectNode object) {
Integer count = Arrays.stream(heroFields).reduce(0, (c, field)->c + (object.has(field)?1:0),(a,b)->a+b) ;
if(count == 0){
return false;
} else if (count == heroFields.length){
return true;
}
throw new IllegalStateException("ide majd valmi kell még testya!");
}
private Hero buildHero(ObjectNode object){
buildEntity(object);
int xpPerLevel = object.get("xp_per_level").asInt();
int dmgIncreacePerLevel = object.get("dmg_increase_per_level").asInt();
int hpIncreasePerLevel = object.get("hp_increase_per_level").asInt();
float cooldownMultiplierPerLevel = object.floatValue();
}
private Entity buildEntity(ObjectNode object){
double health = object.get("health").asDouble();
double attack = object.get("attack").asDouble();
double defense = object.get("defense").asDouble();
double cooldown = object.get("cooldown").asDouble();
String name= object.get("name").asText();
String lore= object.get("lore").asText();
}
'''
Nem találja a buld metódusokat az objectmapper. Van ötleted miért nem?
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Builder class `EntityDeserializer` does not have build method (name: 'build')
at [Source: (File); line: 1, column: 1]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1764)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder.buildBuilderBased(BeanDeserializerBuilder.java:429)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBuilderBasedDeserializer(BeanDeserializerFactory.java:360)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBuilderBasedDeserializer(BeanDeserializerFactory.java:169)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:342)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:591)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4733)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4594)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3413)
at Main.main(Main.java:24)
Ehhez az JsonDeserializerhez kellek írni egy Serializert is vagy az entity/hero felel meg annak?