Jackson JSON parsen

Luckshotx

Mitglied
Hallo,

derzeit versuche ich mit Jackson eine API im JSON Format zu parsen. Wenn ich das ganze im kleinen Rahmen versuche schaffe ich es erfolgreich auf einzelne Daten zuzugreifen. Wenn das Ganze nun komplexer wird und Werte doppelt vorkommen komme ich leider nicht mehr zurecht. Verwendet habe ich Jackson und jsonschema2pojo.

Ich würde euch bitten, mir an einem kleinen Beispiel zu zeigen, wie ich an bestimmte Daten herankomme, in meinem Fall würde ich gerne den Bereich mit der id 49479 mit allen relevanten Daten, wie z.B. dem Slot und den Attributen ausgeben. Ein Denkanstoß wäre natürlich auch super oder verlinkt mir gerne auch leicht verständliche Anleitungen dazu.
Leider weiß ich dort überhaupt nicht, wie ich nun die einzelnen Klassen anspreche um an die relevanten Daten zukommen, aber schaut euch dazu am besten mal meinen Ansatz an. Die meisten Anleitungen haben leider nur die leichte Fälle behandelt.

Code:
{
  "equipment": [
    {
      "id": 63473,
      "slot": "HelmAquatic",
      "binding": "Character",
      "bound_to": "User123"
    },
    {
      "id": 49479,
      "slot": "Backpack",
      "stats": {
        "id": 584,
        "attributes": {
          "Power": 63,
          "Precision": 40,
          "CritDamage": 40
        }
      },
      "binding": "Account"
    },
    {
      "id": 48073,
      "slot": "Coat",
      "binding": "Account"
    },
    {
      "id": 48072,
      "slot": "Boots",
      "binding": "Account"
    },
    {
      "id": 48074,
      "slot": "Gloves",
      "binding": "Account"
    },
    {
      "id": 48075,
      "slot": "Helm",
      "binding": "Account"
    },
    {
      "id": 48076,
      "slot": "Leggings",
      "binding": "Account"
    },
    {
      "id": 48077,
      "slot": "Shoulders",
      "binding": "Account"
    },
    {
      "id": 39232,
      "slot": "Accessory1",
      "binding": "Account"
    },
    {
      "id": 39233,
      "slot": "Accessory2",
      "binding": "Account"
    },
    {
      "id": 75669,
      "slot": "Ring1",
      "binding": "Account"
    },
    {
      "id": 76024,
      "slot": "Ring2",
      "binding": "Account"
    },
    {
      "id": 39272,
      "slot": "Amulet",
      "binding": "Account"
    },
    {
      "id": 14661,
      "slot": "WeaponAquaticA",
      "upgrades": [
        24618,
        24612
      ],
      "binding": "Character",
      "bound_to": "User123"
    },
    {
      "id": 30704,
      "slot": "WeaponA1",
      "upgrades": [
        24599
      ],
      "stats": {
        "id": 161,
        "attributes": {
          "Power": 251,
          "Precision": 179,
          "CritDamage": 179
        }
      },
      "binding": "Account"
    },
    {
      "id": 14443,
      "slot": "WeaponB1",
      "skin": 5209,
      "binding": "Character",
      "bound_to": "User123"
    },
    {
      "id": 22997,
      "slot": "Sickle",
      "binding": "Account",
      "charges": 32
    },
    {
      "id": 23000,
      "slot": "Axe",
      "binding": "Account",
      "charges": 33
    },
    {
      "id": 23001,
      "slot": "Pick",
      "binding": "Account",
      "charges": 63
    }
  ]
}

Code:
import java.net.URL;

import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {

   public static void main(String[] args) throws Exception {              
       URL equipmentURL = new URL("https://api.guildwars2.com/v2/characters/User123/equipment?access_token=8B436065-E98A-924C-803D");
       
       Example example = null;
       example = mapper.readValue(equipmentURL, Example.class);
       
       System.out.println(example.getEquipment());
   }
}

Code:
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "equipment"
})
public class Example {

    @JsonProperty("equipment")
    private List<Equipment> equipment = null;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("equipment")
    public List<Equipment> getEquipment() {
        return equipment;
    }

    @JsonProperty("equipment")
    public void setEquipment(List<Equipment> equipment) {
        this.equipment = equipment;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

Code:
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "id",
    "slot",
    "binding",
    "bound_to",
    "stats",
    "upgrades",
    "skin",
    "charges"
})
public class Equipment {

    @JsonProperty("id")
    private Integer id;
    @JsonProperty("slot")
    private String slot;
    @JsonProperty("binding")
    private String binding;
    @JsonProperty("bound_to")
    private String boundTo;
    @JsonProperty("stats")
    private Stats stats;
    @JsonProperty("upgrades")
    private List<Integer> upgrades = null;
    @JsonProperty("skin")
    private Integer skin;
    @JsonProperty("charges")
    private Integer charges;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("id")
    public Integer getId() {
        return id;
    }

    @JsonProperty("id")
    public void setId(Integer id) {
        this.id = id;
    }

    @JsonProperty("slot")
    public String getSlot() {
        return slot;
    }

    @JsonProperty("slot")
    public void setSlot(String slot) {
        this.slot = slot;
    }

    @JsonProperty("binding")
    public String getBinding() {
        return binding;
    }

    @JsonProperty("binding")
    public void setBinding(String binding) {
        this.binding = binding;
    }

    @JsonProperty("bound_to")
    public String getBoundTo() {
        return boundTo;
    }

    @JsonProperty("bound_to")
    public void setBoundTo(String boundTo) {
        this.boundTo = boundTo;
    }

    @JsonProperty("stats")
    public Stats getStats() {
        return stats;
    }

    @JsonProperty("stats")
    public void setStats(Stats stats) {
        this.stats = stats;
    }

    @JsonProperty("upgrades")
    public List<Integer> getUpgrades() {
        return upgrades;
    }

    @JsonProperty("upgrades")
    public void setUpgrades(List<Integer> upgrades) {
        this.upgrades = upgrades;
    }

    @JsonProperty("skin")
    public Integer getSkin() {
        return skin;
    }

    @JsonProperty("skin")
    public void setSkin(Integer skin) {
        this.skin = skin;
    }

    @JsonProperty("charges")
    public Integer getCharges() {
        return charges;
    }

    @JsonProperty("charges")
    public void setCharges(Integer charges) {
        this.charges = charges;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

Code:
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "Power",
    "Precision",
    "CritDamage"
})
public class Attributes {

    @JsonProperty("Power")
    private Integer power;
    @JsonProperty("Precision")
    private Integer precision;
    @JsonProperty("CritDamage")
    private Integer critDamage;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("Power")
    public Integer getPower() {
        return power;
    }

    @JsonProperty("Power")
    public void setPower(Integer power) {
        this.power = power;
    }

    @JsonProperty("Precision")
    public Integer getPrecision() {
        return precision;
    }

    @JsonProperty("Precision")
    public void setPrecision(Integer precision) {
        this.precision = precision;
    }

    @JsonProperty("CritDamage")
    public Integer getCritDamage() {
        return critDamage;
    }

    @JsonProperty("CritDamage")
    public void setCritDamage(Integer critDamage) {
        this.critDamage = critDamage;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

Code:
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "id",
    "attributes"
})
public class Stats {

    @JsonProperty("id")
    private Integer id;
    @JsonProperty("attributes")
    private Attributes attributes;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    @JsonProperty("id")
    public Integer getId() {
        return id;
    }

    @JsonProperty("id")
    public void setId(Integer id) {
        this.id = id;
    }

    @JsonProperty("attributes")
    public Attributes getAttributes() {
        return attributes;
    }

    @JsonProperty("attributes")
    public void setAttributes(Attributes attributes) {
        this.attributes = attributes;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}
 
Naja, eig recht einfach...
aus example die Liste getten, mit Streams oder Schleifen das Equipment mit der gesuchten ID raussuchen, und dann ausgeben, das ist ab da pures Java und hat nichts mehr mit JSON zu tun 😉

Was verstehst du denn nicht?
 
Naja, eig recht einfach...
aus example die Liste getten, mit Streams oder Schleifen das Equipment mit der gesuchten ID raussuchen, und dann ausgeben, das ist ab da pures Java und hat nichts mehr mit JSON zu tun 😉

Was verstehst du denn nicht?

Super, vielen Dank! Das ich mit example arbeiten muss war wohl mein Stolperstein. Wie bekomme ich den nun am elegantesten raus, wie viele Einträge bei den Attributen vorhanden sind?

Einmal die Lösung für die Nachwelt:
Code:
System.out.println("Id: " + example.getEquipment().get(1).getId());
System.out.println("Slot: " + example.getEquipment().get(1).getSlot());
System.out.println("Stats:");
System.out.println("   Attributes:");
System.out.println("      Power: " + example.getEquipment().get(1).getStats().getAttributes().getPower());
System.out.println("      Precision: " + example.getEquipment().get(1).getStats().getAttributes().getPrecision());
System.out.println("      CritDamage: " + example.getEquipment().get(1).getStats().getAttributes().getCritDamage());
System.out.println("Binding: " + example.getEquipment().get(1).getBinding());
 
Wie meinst du das, wie viele Stats zu einem Equipment gehören?
Genau. Aber woher weiß ich welche Stats es eigentlich sind? Ich kann denke ich mal schlecht alle möglichen Werte durchlaufen und schauen ob ich was zurückbekomme, dann müsste wiederrum alle Fälle abgedeckt sein. Setzt natürlich voraus, dass es mehr als drei Werte gibt.

example.getEquipment().get(1).getStats().getAttributes())
Liefert mir ja nur die Adresse?

Die Lösung mit get(1) ist übrigens echt unschön, wenn du einen Eintrag mit einer bestimmten ID möchtest, was zumindest deine Frage war...
Das stimmt natürlich, hätte mir dann mit size() die Länge geholt und wäre die Liste mit einer Schleife durchlaufen.
 
Genau. Aber woher weiß ich welche Stats es eigentlich sind? Ich kann denke ich mal schlecht alle möglichen Werte durchlaufen und schauen ob ich was zurückbekomme, dann müsste wiederrum alle Fälle abgedeckt sein. Setzt natürlich voraus, dass es mehr als drei Werte gibt.
Naja, doch. Wie denn sonst, als durchlaufen und gucken was da ist, soll man denn sonst sehen was da ist?

example.getEquipment().get(1).getStats().getAttributes())
Liefert mir ja nur die Adresse?

Naja, das gibt die das Attribute-Objekt, damit kannst du dann weitermachen, je nachdem was du machen willst...

Das stimmt natürlich, hätte mir dann mit size() die Länge geholt und wäre die Liste mit einer Schleife durchlaufen.
Oder die Stream-API benutzen, damit gehts deutlich einfacher 😉
 
Java:
Optional<Equipment> equipment = example.getEquipment().stream() //Stream erzeugen
.filter(e -> e.getId().equals(49479)) //Nur das Equipment im Stream lassen, dessen ID==49479 ist
.findAny(); //ein Element zurückgeben (sollte bei IDs genau eins sein), ist in einem Optional gekapselt, da es auch keins sein kann (zb hier, wenn es die ID nicht gibt)

Mit dem optional kann man dann entsprechend weitermachen 😉
 

Zurück
Oben