java - Gson 抛出 MalformedJsonException 和其他异常

标签 java json eclipse jar gson

我尝试使用 Gson 将数据保存到 txt 文件中的 json 字符串,然后使用 Gson 恢复它。如果我在 eclipse 中做的话,一切都会顺利。但是打包成jar的时候,Gson会抛出异常。

这是保存文件的代码。

String gsonStr = gson.toJson(masterShips);  // masterShips is ArrayList<Ship>
BufferedWriter writer = null;
try {
    writer = new BufferedWriter(new FileWriter("D:\\master_ship.txt"));
    writer.write(gsonStr);
} catch (IOException e) {
    System.err.println(e);
} finally {
    if (writer != null) {
        try {
            writer.close();
        } catch (IOException e) {
            System.err.println(e);
        }
    }
}

然后我使用此代码在 Eclipse 中读取该文件(并且它有效):

Scanner in = new Scanner(new FileReader("D:\\master_ship.txt"));

String str = in.nextLine();
Log.toDebug(str);
in.close();
JsonParser parser = new JsonParser();
JsonElement je = parser.parse(str);
JsonArray ja = je.getAsJsonArray();
for (int i=0; i<ja.size(); ++i) { 
    ... 
}

但是打包成jar后在cmd中运行,出现异常:

Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.
stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malform
ed JSON at line 1 column 4
        at com.google.gson.JsonParser.parse(JsonParser.java:65)
        at com.google.gson.JsonParser.parse(JsonParser.java:45)
        at kan.util.Master.loadMasterShip(Master.java:44)
        at kan.util.Master.load(Master.java:27)
        at kan.Main.main(Main.java:22)
Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLeni
ent(true) to accept malformed JSON at line 1 column 4
        at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1505)
        at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1386)
        at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:531)
        at com.google.gson.stream.JsonReader.peek(JsonReader.java:414)
        at com.google.gson.JsonParser.parse(JsonParser.java:60)
        ... 4 more

根据异常的提示,我更改了代码,在eclipse中仍然有效:

Scanner in = new Scanner(new FileReader("D:\\master_ship.txt"));

String str = in.nextLine();
in.close();

Reader reader = new StringReader(str);
JsonReader jr = new JsonReader(reader);
jr.setLenient(true);
JsonParser parser = new JsonParser();
JsonElement je = parser.parse(jr);
JsonArray ja = je.getAsJsonArray();
for (int i=0; i<ja.size(); ++i) { 
... 
}

但是 jar 失败并抛出

Exception in thread "main" java.lang.IllegalStateException: This is not a JSON A
rray.
    at com.google.gson.JsonElement.getAsJsonArray(JsonElement.java:106)
    at kan.util.Master.loadMasterShip(Master.java:58)
    at kan.util.Master.load(Master.java:30)
    at kan.Main.main(Main.java:22)

按照 Sotirios 的建议,我缩短了数组列表的长度,当我将船只数量增加到 4 时,出现了问题。这是 json:

[{"id":1,"name":"睦月","type":2,"rank":2,"fuelMax":15,"bulletMax":15,"slotNum":2,"speed":10,"afterLv":20,"afterId":254,"range":1,"powerups":[1,1,0,0]},{"id":2,"name":"如月","type":2,"rank":1,"fuelMax":15,"bulletMax":15,"slotNum":2,"speed":10,"afterLv":20,"afterId":255,"range":1,"powerups":[0,1,0,0]},{"id":6,"name":"長月","type":2,"rank":1,"fuelMax":15,"bulletMax":15,"slotNum":2,"speed":10,"afterLv":20,"afterId":258,"range":1,"powerups":[0,1,0,0]},{"id":7,"name":"三日月","type":2,"rank":1,"fuelMax":15,"bulletMax":15,"slotNum":2,"speed":10,"afterLv":20,"afterId":260,"range":1,"powerups":[0,1,0,0]}]
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ↑ colunm 473

Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.
stream.MalformedJsonException: Unterminated object at line 1 column 473
        at com.google.gson.internal.Streams.parse(Streams.java:56)
        at com.google.gson.JsonParser.parse(JsonParser.java:84)
        at kan.util.Master.loadMasterShip(Master.java:55)
        at kan.util.Master.load(Master.java:30)
        at kan.Main.main(Main.java:22)
Caused by: com.google.gson.stream.MalformedJsonException: Unterminated object at
 line 1 column 473
        at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1505)
        at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:480)
        at com.google.gson.stream.JsonReader.hasNext(JsonReader.java:403)
        at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:
666)
        at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:
659)
        at com.google.gson.internal.bind.TypeAdapters$25.read(TypeAdapters.java:
642)
        at com.google.gson.internal.Streams.parse(Streams.java:44)
        ... 4 more

任何人都可以帮我解决这个问题,您将非常感激!

最佳答案

使用此类

import java.util.List;

public class GsonResponse
{
    public int id;
    public String name;
    public int type;
    public int rank;
    public int fuelMax;
    public int bulletMax;
    public int slotNum;
    public int speed;
    public int afterLv;
    public int afterId;
    public int range;
    public List<Integer> powerups;
    /**
     * @return the id
     */
    public int getId() {
        return id;
    }
    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
    /**
     * @return the type
     */
    public int getType() {
        return type;
    }
    /**
     * @param type the type to set
     */
    public void setType(int type) {
        this.type = type;
    }
    /**
     * @return the rank
     */
    public int getRank() {
        return rank;
    }
    /**
     * @param rank the rank to set
     */
    public void setRank(int rank) {
        this.rank = rank;
    }
    /**
     * @return the fuelMax
     */
    public int getFuelMax() {
        return fuelMax;
    }
    /**
     * @param fuelMax the fuelMax to set
     */
    public void setFuelMax(int fuelMax) {
        this.fuelMax = fuelMax;
    }
    /**
     * @return the bulletMax
     */
    public int getBulletMax() {
        return bulletMax;
    }
    /**
     * @param bulletMax the bulletMax to set
     */
    public void setBulletMax(int bulletMax) {
        this.bulletMax = bulletMax;
    }
    /**
     * @return the slotNum
     */
    public int getSlotNum() {
        return slotNum;
    }
    /**
     * @param slotNum the slotNum to set
     */
    public void setSlotNum(int slotNum) {
        this.slotNum = slotNum;
    }
    /**
     * @return the speed
     */
    public int getSpeed() {
        return speed;
    }
    /**
     * @param speed the speed to set
     */
    public void setSpeed(int speed) {
        this.speed = speed;
    }
    /**
     * @return the afterLv
     */
    public int getAfterLv() {
        return afterLv;
    }
    /**
     * @param afterLv the afterLv to set
     */
    public void setAfterLv(int afterLv) {
        this.afterLv = afterLv;
    }
    /**
     * @return the afterId
     */
    public int getAfterId() {
        return afterId;
    }
    /**
     * @param afterId the afterId to set
     */
    public void setAfterId(int afterId) {
        this.afterId = afterId;
    }
    /**
     * @return the range
     */
    public int getRange() {
        return range;
    }
    /**
     * @param range the range to set
     */
    public void setRange(int range) {
        this.range = range;
    }
    /**
     * @return the powerups
     */
    public List<Integer> getPowerups() {
        return powerups;
    }
    /**
     * @param powerups the powerups to set
     */
    public void setPowerups(List<Integer> powerups) {
        this.powerups = powerups;
    }    
}

只需在您解析的位置添加以下代码

String strJson = "[{\"id\":1,\"name\":\"睦月\",\"type\":2,\"rank\":2,\"fuelMax\":15,\"bulletMax\":15,\"slotNum\":2,\"speed\":10,\"afterLv\":20,\"afterId\":254,\"range\":1,\"powerups\":[1,1,0,0]},{\"id\":2,\"name\":\"如月\",\"type\":2,\"rank\":1,\"fuelMax\":15,\"bulletMax\":15,\"slotNum\":2,\"speed\":10,\"afterLv\":20,\"afterId\":255,\"range\":1,\"powerups\":[0,1,0,0]},{\"id\":6,\"name\":\"長月\",\"type\":2,\"rank\":1,\"fuelMax\":15,\"bulletMax\":15,\"slotNum\":2,\"speed\":10,\"afterLv\":20,\"afterId\":258,\"range\":1,\"powerups\":[0,1,0,0]},{\"id\":7,\"name\":\"三日月\",\"type\":2,\"rank\":1,\"fuelMax\":15,\"bulletMax\":15,\"slotNum\":2,\"speed\":10,\"afterLv\":20,\"afterId\":260,\"range\":1,\"powerups\":[0,1,0,0]}]";
        GsonResponse gsonResponse = null;
        try {
            gsonResponse = new Gson().fromJson(strJson,
                    GsonResponse.class);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }

关于java - Gson 抛出 MalformedJsonException 和其他异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20778497/

相关文章:

java - 项目 'starter' 中所需库 : spring-core-4. 0.1.RELEASE.jar 的类型存档无法读取或不是有效的 ZIP 文件

java - MongoDB 变更流

java - 每 X 秒打印一个单词

ios - Obj-C 获取 JSON 键名

json - 在 Swift Firebase 中滚动时分页

java.lang.ClassNotFoundException : com. mysql.jdbc.Driver 错误,即使在导入库之后

Eclipse:在“库”选项卡中,所有按钮均被禁用

javascript - 如何确定 HTML 元素何时在 Android WebView 中获得焦点?

java - 导致无限循环的异常处理(java)

javascript - jQuery getJSON 从 API 如何访问对象?