2014-03-25 51 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