0

I am creating an application which it will send http request to a web server. The return will be in json. Here is how the json look like

[//I used a tool to make it beautiful and easy to read.
  {
    "item_name": "Adame",
    "item_type": "Special",
    "item": "Chestplate",
    "item_min_lvl": "50",
    "enchantment": {
      "health": "0.3",
      "dam": "24%",
      "life": "0.1",
      "xp": "24%",
      "loot": "22%"
    },
    "def": "73"
  },
  {
    "item_name": "Sticks'",
    "item_type": "Unique",
    "item": "Stick",
    "item_min_lvl": "4",
    "enchantment": {
      "health": "0.6",
      "mana": "1",
      "dam": "12%",
      "life": "0.3",
      "xp": "17%",
      "loot": "17%"
    },
    "min_dam": "39",
    "max_dam": "34"
  },
  {
    "item_name": "Sword'",
    "item_type": "Unique",
    "item": "Sword",
    "item_min_lvl": "8",
    "enchantment": [], //colonm 30 is [
    "min_dam": "9",
    "max_dam": "10"
  }
]

Are you can see, the data inside the array are different. I got this error, Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 30. This is my code:

MyJSON[] data = gson.from(jsonString, MyJSON[].class);

class MyJSON {
    String item_name;
    String item_type;
    String item;
    String item_min_lvl;
    Enchantment enchantment;
    String min_dam;
    String max_dam;

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();

        builder.append("\nitem_name:").append(item_name);
        builder.append("\nitem_type:").append(item_type);
        builder.append("\nitem:").append(item);
        builder.append("\nitem_min_lvl:").append(item_min_lvl);

        builder.append("\n\nEnchantment Details:");
        builder.append("\nhealth:").append(enchantment.health);
        builder.append("\ndam:").append(enchantment.dam);
        builder.append("\nlife:").append(enchantment.life);
        builder.append("\nxp:").append(enchantment.xp);
        builder.append("\nloot:").append(enchantment.loot);
        return builder.toString();
    }
}

class Enchantment {
    String health;
    String dam;
    String life;
    String xp;
    String loot;
    String mana;
}

Can anyone help me to improve my code so my code an parse the json in different case. Thanks in advanced. (P.s. that's not my web server so I can't do anything with the json)

1
  • That doesn't look like valid JSON, though. Commented May 18, 2014 at 5:11

3 Answers 3

2

Basically this line of JSON

"enchantment": [], //colonm 30 is [

doesn't match your POJO. You're expecting an Enchantment object, but the JSON is giving you an array. Fix your JSON to return an empty JSON object or nothing at all for the enchantment pair.

"enchantment": {}
Sign up to request clarification or add additional context in comments.

4 Comments

How do I fix? I said this is not my web server.
@Jeremy Well, you can't map the JSON to different POJOs. Your only other option is to not map it to a POJO and either use JsonNode or a LinkedHashMap as the Java representation.
@Jeremy In your gson fromJson(..), try using JsonElement (or JsonObject). I don't have a computer where I can test it right now.
Can you write me some example code please? I really I no idea about JsonElement or JsonObject
0

This is a Valid JSON unless you have added comments just to show lines where is the issue?

Comments should not be part of JSON.

Here is the code that I have already shared you at you another post Java - Json deserialize data [].

You have to use ArrayList<Map<String, Object>> because the entries in the JSON string are not symmetric. You can't convert it into POJO in this case.

StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new FileReader(new File("resources/json2.txt")));
String line = null;
while ((line = reader.readLine()) != null) {
    builder.append(line);
}
reader.close();

Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<Map<String, Object>>>() {
}.getType();
ArrayList<Map<String, Object>> list = gson.fromJson(builder.toString(), listType);

for (Map<String, Object> json : list) {
    for (String key : json.keySet()) {
        System.out.println(key + ":" + json.get(key));
    }
    System.out.println("===========");
}

output:

item_name:Adame
item_type:Special
item:Chestplate
item_min_lvl:50
enchantment:{health=0.3, dam=24%, life=0.1, xp=24%, loot=22%}
def:73
===========
item_name:Sticks'
item_type:Unique
item:Stick
item_min_lvl:4
enchantment:{health=0.6, mana=1, dam=12%, life=0.3, xp=17%, loot=17%}
min_dam:39
max_dam:34
===========
item_name:Sword'
item_type:Unique
item:Sword
item_min_lvl:8
enchantment:[]
min_dam:9
max_dam:10
===========

EDIT

enchantment return something like

enchantment:{health=0.6, mana=1, dam=12%, life=0.3, xp=17%, loot=17%}. 

How can I get for example health?

Type mapType = new TypeToken<Map<String, String>>() {
}.getType();
String string = "{health=0.6, mana=1, dam=12%, life=0.3, xp=17%, loot=17%}";
Map<String, String> map = new Gson().fromJson(string, mapType);
for (String key : map.keySet()) {
    System.out.println(key + ":" + map.get(key));
}

output:

health:0.6
mana:1
dam:12%
life:0.3
xp:17%
loot:17%

5 Comments

This will work in all the case whatever is the JSON string. whether it contains enchantment:[] or enchantment:{} or not at all.
enchantment return something like enchantment:{health=0.6, mana=1, dam=12%, life=0.3, xp=17%, loot=17%}. How can I get for example health? Sorry I am stupid
Treat it as JSON string and again convert it into appropriate object type .Should I code for you?
I have added it my post as well. just remove enchantment: then then parse rest JSON string into Map
Check out my latest question please :3
0

You can create a custom list type in Gson's fromJson() method to map it to a list of POJOs

Type listType = new TypeToken<ArrayList<Enhancement>>() {}.getType();
List<Enhancement> enhancements = new Gson().fromJson(jsonString, listType);

You will get a List<Enhancement>.

1 Comment

You can cast it to List<Enhancement> or directly collect it to List<Enhancement>! It will work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.