2014-03-25 52 views
1

我已經嘗試了一切,但解決方案是如此醜陋,我真的想要一個直截了當的答案,如果這可以改善(這意味着如果我需要使用不同的實現)。用GSON解析地圖的JSON地圖

問題在於地圖地圖與GSON:

讓我根據螢火蟲這樣的響應:

{"id": 2, "result": {"FirstWorld": {"FirstValue": 5, ... }, "SecondWorld":{"FirstValue": 5, ....}}, "error":null } 

大約有200 "Values",但只有兩個"Worlds"。這是我迄今爲止解析它在我ControlService類:

public void RegisterValues(String [] Names, AsyncCallback<Map<String,RegisterValues>> callback); 

public class RegisterValues 
    { 
     int FirstValue; 
     int SecondValue; 
     ... And so on 200 times !!! 

所以我訪問數據,像這樣:

service_.RegisterValues(Names, new AsyncCallback<ControlService.RegisterValues>() 
       { 
       public void onSuccess(GlibControlService.RegisterValues result) 
        { 
         String test = "FirstValue"; 

         String message="Result for channel 1 is "; 
         for(String Name : result.keySet()) message+=Name+"="+result.get(Name); 

但正如你所看到的,這將是很長的。另一個問題是一些「價值觀」中有&符號,這意味着我不能在這種方法中使用它們,例如:

@SerializedName("One&Two") // Ampersand not allowed in name 
int OneTwo; //gives Invalid JSON response apparently 

有沒有人有更好的方法來做到這一點?該工程

編輯代碼:

private ControlService service_; 

service_.connectedNames(new String[0], new AsyncCallback<String[]>() { 

      public void onSuccess(String[] result) 
      { 
       List_.removeItem(0); 
       Names = result; 
       for(String Name : result) { 

        List_.addItem(Name); 
       } 
       List_.setEnabled(true); 
      } 
      public void onFailure(Throwable why) 
      { 
       List_.removeItem(0); 
       List_.addItem("Server error!"); 
      } 
     }); 

然後在我ControlService類,我有這樣的:

@RpcImpl(version=RpcImpl.Version.V2_0,transport=RpcImpl.Transport.HTTP_POST) 
public interface ControlService extends RemoteJsonService 
{ 

    public void connectedNames(String [] Names, AsyncCallback<String[]> callback); 

這完美的作品。

我試圖在我的ControlService添加此做一個非常相似的方式:

public void RegisterValues(String [] Names, AsyncCallback<Map< String,Map<String, Integer>> callback); 

等等,確保Map<String, Map<String, Integer>>也是在結構onSucess()一部分了。然而這導致我的程序崩潰。在我看來,它不喜歡嵌套的地圖。但是,如果成員名稱與JSON字段匹配,GSON將自動解析對象。所以我用RegisterValues自動強制GSON解析這個。

堆棧跟蹤:

[ERROR] Errors in 'generated://AF9BA58B045D92E7896CD657C9CC5FAF/example/client/ControlService_JsonProxy.java' 
     [ERROR] Line 18: INSTANCE cannot be resolved or is not a field 
     See snapshot: /var/folders/pf/56b3mznn35gg741rlsqq424m0000gp/T/example.client.ControlService_JsonProxy2948240672238331252.java 

這就是爲什麼我認爲使用的AsyncCallback GSON不能自動解析嵌套地圖。根據下面的建議進行HTTP調用可能會更好。

+0

_This但是導致我的程序crash_。你有堆棧跟蹤嗎? – rpax

+0

完成,但它不是很有幫助。 – fiz

+0

@rpax我不確定是否還有其他事情可以寄給我 – fiz

回答

2

最好的方法是將發佈的回覆包裝到一個類中。

{"id": 2, "result": {"FirstWorld": {"FirstValue": 5, ... }, "SecondWorld":{"FirstValue": 5, ....}}, "error":null } 

import java.util.Map; 

public class Response { 

    private int id; 
    private Map<String, Map<String, Integer>> result; 
    private String error; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public Map<String, Map<String, Integer>> getResult() { 
     return result; 
    } 

    public void setResult(Map<String, Map<String, Integer>> result) { 
     this.result = result; 
    } 

    public String getError() { 
     return error; 
    } 

    public void setError(String error) { 
     this.error = error; 
    } 

} 

我這個測試並運行良好。

static String json = "{\"id\":2,\"result\":{\"FirstWorld\":{\"FirstValue\":5,\"SecondValue\":6},\"SecondWorld\":{\"FirstValue\":5,\"SecondValue\":6}},\"error\":null}"; 

    public static void main(String[] args) { 


     Gson g= new Gson(); 
     Response b=g.fromJson(json, Response.class); 
     System.out.println(g.toJson(b)); 
    } 

如果你需要有RegisterValues類中聲明, 你只需要使用這個類來代替結果Map<String, Integer>,可能延長Map

+0

Thankyou非常適合你回覆。我現在嘗試 - 但我很努力地看到我將如何適應我的AsyncCallback方法 – fiz

+0

@fiz也許延長'AsyncCallback'類 – rpax

+0

我現在就來說說這個。我剛剛開始學習Java。如果這樣做,並且您在paypall上有「給我買啤酒」,我會很樂意捐出 – fiz