2013-12-26 2 views
0

Я попытался сохранить данные в строку json в txt-файле с помощью Gson, а затем восстановить его с помощью Gson. Все идет хорошо, если я делаю это в затмении. Но когда он упакован в банку, Гисн выбрасывает Исключения.Gson throws MalformedJsonException и другие исключения

Вот код для сохранения файла.

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); 
     } 
    } 
} 

Затем я прочитал файл в затмении, используя этот код (и он работает):

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) { 
    ... 
} 

Но после того, как упакована в банку и запустить в ЦМД, происходит исключение:

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 

Согласно намеку на исключение, я изменил свой код и все еще работает в затмении:

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) { 
... 
} 

Но банку не удалось, и бросает

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) 

Как было предложено Сотирия я сократил длину ArrayList вниз, и когда я увеличить число кораблей до 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 

Может кто-нибудь помочь мне с этим, вы будете reaally preciated!

+1

Давайте посмотрим ваш JSON. –

+0

@SotiriosDelimanolis Это действительно длинный json, я не знаю, как вам показать. Это ArrayList из нескольких сотен кораблей с более чем 10 параметрами. – bijiDango

+1

Сократите это до наименьшего количества, которое воспроизведет проблему. –

ответ

0

Используйте этот класс

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(); 
     } 
+0

Спасибо, но ваш действительно не является хорошим решением, учитывая усилие, которое вы добавляете в добавление кавычек. А также я решил эту проблему. Похоже, что использование моей системы Scanner делает странное декодирование. Когда я изменил схему загрузки на «InputStream», она работает правильно. – bijiDango

Смежные вопросы