Android JSON阅读器-IllegalStateException;预期名称,但为字符串 [英] android JSON reader - IllegalStateException; expected name but was string

查看:94
本文介绍了Android JSON阅读器-IllegalStateException;预期名称,但为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Json Reader来解析.json文件,以将记录插入到我的数据库中,但是我在读取文件时遇到了问题.

I'm trying to use a Json Reader to parse through a .json file to insert records into my database but i'm having a problem reading through the file.

我特意用try/catch子句打开了用于解析/读取器的方法,这样我就可以知道错误是从哪里来的.

I intentionally opened the methods for parsing/reader with a try/catch clause so i can see what the error was coming from.

这是json解析器/阅读器类:

Here is the json Parser/Reader class:

package cybertech.productions.servicehelpers;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import android.content.Context;

import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;

public class JsonParser {

    public void readCardJsonStream1(String cardSet, CarddbAdapter yugiohDB,
            Context context) throws IOException {

        URL test = new URL(cardSet);
        InputStream in = new BufferedInputStream(test.openStream());

        JsonReader reader = new JsonReader(new InputStreamReader(in,
                "ISO-8859-1"));

        String s, s1, s2, levelstr, rankstr, atkstr, defstr, setnumstr, cardpasstr;

        int numTotalElements = 0;
        int elementsParsed = 0;

        reader.beginObject();
        s = reader.nextName();

        reader.beginObject();
        while (reader.hasNext()) {

            s = reader.nextName();
            if (s.equalsIgnoreCase("p")) { // cards

                reader.beginObject();
                while (reader.hasNext()) {
                    s1 = reader.nextName();
                    if (s1.equalsIgnoreCase("o")) { // card
                        YugiohCard c;
                        reader.beginArray();
                        while (reader.hasNext()) {

                            reader.beginObject();
                            c = new YugiohCard();
                            while (reader.hasNext()) {
                                s2 = reader.nextName();
                                if (s2.equalsIgnoreCase("a")) { // name
                                    c.name = reader.nextString();
                                } else if (s2.equalsIgnoreCase("b")) { // type
                                    c.type = reader.nextString();
                                } else if (s2.equalsIgnoreCase("c")) { // attribute_type
                                    c.attributeType = reader.nextString();
                                } else if (s2.equalsIgnoreCase("d")) { // summon_requirements
                                    c.summonRequirements = reader.nextString();
                                } else if (s2.equalsIgnoreCase("e")) { // description
                                    c.description = reader.nextString();
                                } else if (s2.equalsIgnoreCase("f")) { // spell
                                                                        // speed
                                    c.spellSpeed = reader.nextString();

                                } else if (s2.equalsIgnoreCase("g")) { // level_stars
                                    levelstr = reader.nextString();
                                    c.levelStars = Integer.parseInt(levelstr);
                                } else if (s2.equalsIgnoreCase("h")) { // rank_stars
                                    rankstr = reader.nextString();
                                    c.rankStars = Integer.parseInt(rankstr);
                                } else if (s2.equalsIgnoreCase("i")) { // atk_points
                                    atkstr = reader.nextString();
                                    c.atk_stat = Integer.parseInt(atkstr);
                                } else if (s2.equalsIgnoreCase("j")) { // def_points
                                    defstr = reader.nextString();
                                    c.def_stat = Integer.parseInt(defstr);
                                } else if (s2.equalsIgnoreCase("n")) { // set
                                                                        // initials
                                    c.setinit = reader.nextString();
                                } else if (s2.equalsIgnoreCase("k")) { // set_number
                                    setnumstr = reader.nextString();
                                    c.setNumber = Integer.parseInt(setnumstr);
                                } else if (s2.equalsIgnoreCase("l")) { // card_number_pass
                                    cardpasstr = reader.nextString();
                                    c.cardnumberPass = Integer
                                            .parseInt(cardpasstr);
                                }
                            }
                            yugiohDB.createDBCard(c);
                            reader.endObject();
                        }
                        reader.endArray();
                    }
                }
                reader.endObject();
            }
            if (s.equalsIgnoreCase("w")) { // num_cards
                numTotalElements = reader.nextInt();
            }
        }
        reader.endObject();
        reader.close();
    }
}

这是我的Json文件:

This is my Json file:

{
    "t": {
        "p": {
            "o": [
                {
                    "a": "Elemental HERO Absolute Zero",
                    "b": "Monster/Fusion/Effect",
                    "c": "WATER",
                    "d": "1 'HERO' monster + 1 WATER monster",
                    "e": "Blows up your field, sucks for you",
                    "f": "NULL",
                    "g": "8",
                    "h": "0",
                    "i": "2500",
                    "j": "2000",
                    "n": "YG04",
                    "k": "001",
                    "l": "40854197"
                },
                {
                    "a": "Elemental HERO Air Neos",
                    "b": "Monster/Fusion/Effect",
                    "c": "WIND",
                    "d": "Hummingbird + Neos",
                    "e": "Returns to extra at end phase",
                    "f": "NULL",
                    "g": "7",
                    "h": "0",
                    "i": "2500",
                    "j": "2000",
                    "n": "STON",
                    "k": "034",
                    "l": "11502550"
                },
                {
                    "a": "Cyber Jar",
                    "b": "Monster/Effect",
                    "c": "DARK",
                    "d": "NULL",
                    "e": "destroys all monsters on the field",
                    "f": "NULL",
                    "g": "3",
                    "h": "0",
                    "i": "900",
                    "j": "900",
                    "n": "MRL",
                    "k": "077",
                    "l": "34124316"
                },
                {
                    "a": "Wind-Up Carrier Zenmaity",
                    "b": "MACHINE/Xyz/Effect",
                    "c": "WATER",
                    "d": "2 Level 3 monsters",
                    "e": "Special summon a wind-up from your hand or deck.",
                    "f": "NULL",
                    "g": "0",
                    "h": "3",
                    "i": "1500",
                    "j": "1500",
                    "n": "ORCS",
                    "k": "044",
                    "l": "81122844"
                },
                {
                    "a": "BRAIN CONTROL",
                    "b": "Spell",
                    "c": "Spell",
                    "d": "NULL",
                    "e": "Pay 800 Life Points to target 1 face-up monster your opponent controls; take control of that target until the End Phase.",
                    "f": "Normal",
                    "g": "0",
                    "h": "0",
                    "i": "0",
                    "j": "0",
                    "n": "LCYW",
                    "k": "074",
                    "l": "87910978"
                },
                {
                    "a": "Ring of Destruction",
                    "b": "Trap",
                    "c": "Trap",
                    "d": "NULL",
                    "e": "Target 1 face-up monster on the field; destroy that target, and if you do, inflict damage to both players equal to that target's ATK.",
                    "f": "Normal",
                    "g": "0",
                    "h": "0",
                    "i": "0",
                    "j": "0",
                    "n": "YG04",
                    "k": "001",
                    "l": "40854197"
                }
            ]
        },
        "v": "2/3/2013"
    }
}

这是我创建的一种方法,用于告知json文件在我的网站上的位置:

Here is a method i created to tell where the json file is located on my site:

public void CreateYUGIsets() throws MalformedURLException, IOException{
        yugiohDB.dropDB();
        JsonParser parser = new JsonParser();
        String cardSetList = "https://sites.google.com/site/yugiohlibrary/patches/test.json";
        parser.readCardJsonStream1(cardSetList, yugiohDB, this);
    }

这也是我也遇到的Logcat错误:

Here is the Logcat error i'm getting too:

05-15 22:48:49.362: E/AndroidRuntime(476): FATAL EXCEPTION: main
05-15 22:48:49.362: E/AndroidRuntime(476): java.lang.RuntimeException: Unable to start activity ComponentInfo{cybertech.productions.yugiohlibrary/cybertech.productions.yugiohlibrary.LoadingScreen}: java.lang.IllegalStateException: Expected a name but was STRING
05-15 22:48:49.362: E/AndroidRuntime(476):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
05-15 22:48:49.362: E/AndroidRuntime(476):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
05-15 22:48:49.362: E/AndroidRuntime(476):  at android.app.ActivityThread.access$1500(ActivityThread.java:117)
05-15 22:48:49.362: E/AndroidRuntime(476):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
05-15 22:48:49.362: E/AndroidRuntime(476):  at android.os.Handler.dispatchMessage(Handler.java:99)
05-15 22:48:49.362: E/AndroidRuntime(476):  at android.os.Looper.loop(Looper.java:123)
05-15 22:48:49.362: E/AndroidRuntime(476):  at android.app.ActivityThread.main(ActivityThread.java:3683)
05-15 22:48:49.362: E/AndroidRuntime(476):  at java.lang.reflect.Method.invokeNative(Native Method)
05-15 22:48:49.362: E/AndroidRuntime(476):  at java.lang.reflect.Method.invoke(Method.java:507)
05-15 22:48:49.362: E/AndroidRuntime(476):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-15 22:48:49.362: E/AndroidRuntime(476):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-15 22:48:49.362: E/AndroidRuntime(476):  at dalvik.system.NativeStart.main(Native Method)
05-15 22:48:49.362: E/AndroidRuntime(476): Caused by: java.lang.IllegalStateException: Expected a name but was STRING
05-15 22:48:49.362: E/AndroidRuntime(476):  at com.google.gson.stream.JsonReader.nextName(JsonReader.java:444)
05-15 22:48:49.362: E/AndroidRuntime(476):  at cybertech.productions.servicehelpers.JsonParser.readCardJsonStream1(JsonParser.java:36)
05-15 22:48:49.362: E/AndroidRuntime(476):  at cybertech.productions.yugiohlibrary.LoadingScreen.CreateYUGIsets(LoadingScreen.java:107)
05-15 22:48:49.362: E/AndroidRuntime(476):  at cybertech.productions.yugiohlibrary.LoadingScreen.onCreate(LoadingScreen.java:41)
05-15 22:48:49.362: E/AndroidRuntime(476):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-15 22:48:49.362: E/AndroidRuntime(476):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
05-15 22:48:49.362: E/AndroidRuntime(476):  ... 11 more

对于logcat中的此特定行: cybertech.productions.servicehelpers.JsonParser.readCardJsonStream1(JsonParser.java:36) 05-15 22:48:49.362:E/AndroidRuntime(476)

For this specific line in the logcat: cybertech.productions.servicehelpers.JsonParser.readCardJsonStream1(JsonParser.java:36) 05-15 22:48:49.362: E/AndroidRuntime(476)

JsonParser类中的第36行是: s = reader.nextName();

Line 36 in the JsonParser class is: s = reader.nextName();

该行恰好在第一个while()循环开始之后.

That line is right after when the first while() loop starts.

任何帮助将不胜感激.

推荐答案

您选择了最繁琐的方法来解析JSON文件.您正在使用的库(Gson)提供了更简单的方法来处理输入.这是一个仍在进行手动解析的示例:

You have chosen the most tedious method to parse your JSON file. The library you're using (Gson) provides much easier ways to process the input. Here is an example that still does manual parsing:

// Your JSON data here
final String json = "";

// Get the array element corresponding to t->p->o, in the data
final JsonElement rootElem = new JsonParser().parse(json);
final JsonArray jsonArr = rootElem.getAsJsonObject()
        .getAsJsonObject("t").getAsJsonObject("p").getAsJsonArray("o");

// Iterate through the JSON array, extracting out card info as we go
final List<Yugioh> cards = new ArrayList<Yugioh>(jsonArr.size());
for (final JsonElement objElem : jsonArr) {
    final JsonObject jsonObj = objElem.getAsJsonObject();
    final Yugioh card = new Yugioh();

    card.setName(jsonObj.get("a").getAsString());
    card.setType(jsonObj.get("b").getAsString());
    card.setAttributeType(jsonObj.get("c").getAsString());
    card.setSummonRequirements(jsonObj.get("d").getAsString());
    card.setDescription(jsonObj.get("e").getAsString());
    card.setSpellSpeed(jsonObj.get("f").getAsString());
    card.setLevelStars(Integer.parseInt(jsonObj.get("g").getAsString()));
    card.setRankStars(Integer.parseInt(jsonObj.get("h").getAsString()));
    card.setAtkStat(Integer.parseInt(jsonObj.get("i").getAsString()));
    card.setDefStat(Integer.parseInt(jsonObj.get("j").getAsString()));
    card.setNumber(Integer.parseInt(jsonObj.get("k").getAsString()));
    card.setCardNumberPass(Integer.parseInt(jsonObj.get("l")
            .getAsString()));
    card.setInit(jsonObj.get("n").getAsString());

    System.out.println(card);
    cards.add(card);
}

请注意代码的可读性.我随意地说明了正确使用getter/setter的方法,并修正了一些变量名.通过在mapper类中指示要从中复制的JSON属性的序列化名称,您可以进一步简化上述示例.例如,使用此映射器类:

Notice how much more readable the code is. I took the liberty of illustrating proper use of getter/setters, and fixed up some of the variable names. You can shorten the example above even further, by indicating in your mapper class, the serialized names of the JSON attributes that you are copying from. Case in point, with this mapper class:

class Yugioh implements Serializable {
    private static final long serialVersionUID = -8125568453376399843L;

    @SerializedName("a")
    private String name;

    @SerializedName("b")
    private String type;

    @SerializedName("c")
    private String attributeType;

    @SerializedName("d")
    private String summonRequirements;

    @SerializedName("e")
    private String description;

    @SerializedName("f")
    private String spellSpeed;

    @SerializedName("g")
    private Integer levelStars;

    @SerializedName("h")
    private Integer rankStars;

    @SerializedName("i")
    private Integer atkStat;

    @SerializedName("j")
    private Integer defStat;

    @SerializedName("k")
    private Integer number;

    @SerializedName("l")
    private Integer cardNumberPass;

    @SerializedName("n")
    private String init;

    public Yugioh() {
        super();
    }

    // Getters/Setters here

    @Override
    public String toString() {
        return String.format("Card %s", getName());
    }
}

您可以大大缩短反序列化代码:

You can shorten up the deserialization code significantly:

// Your JSON data here
final String json = "";

// Deserialize JSON into a bunch of objects
final JsonElement rootElem = new JsonParser().parse(json);
final JsonArray jsonArr = rootElem.getAsJsonObject()
        .getAsJsonObject("t").getAsJsonObject("p").getAsJsonArray("o");
final List<Yugioh> cards = new Gson().fromJson(jsonArr,
        new TypeToken<List<Yugioh>>() {
        }.getType());

System.out.println(cards);

死得很简单.确保阅读 Gson用户指南-它提供了大量有用的信息有关使用该库的信息.

Dead simple. Make sure to read the Gson User Guide - it provides a ton of useful information on utilizing the library.

这篇关于Android JSON阅读器-IllegalStateException;预期名称,但为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆