首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用GSON解析地图的JSON映射

用GSON解析地图的JSON映射
EN

Stack Overflow用户
提问于 2014-03-25 14:09:10
回答 1查看 7K关注 0票数 2

我已经尝试了所有的方法,但是这个解决方案太难看了,我真的想要一个直截了当的答案,看看是否可以改进(这意味着如果我需要使用不同的实现)。

问题在于使用GSON的地图:

根据Firebug给出了这个响应:

代码语言:javascript
复制
{"id": 2, "result": {"FirstWorld": {"FirstValue": 5, ... }, "SecondWorld":{"FirstValue": 5, ....}}, "error":null }

大约有200个"Values",但只有两个"Worlds"。到目前为止,我要在我的ControlService类中解析它:

代码语言:javascript
复制
public void RegisterValues( String [] Names, AsyncCallback<Map<String,RegisterValues>> callback);

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

因此,我访问的数据如下:

代码语言:javascript
复制
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);

但正如你所看到的,这将是非常长的时间。另一个问题是一些“值”中有符号,这意味着我不能在这种方法中使用它们;

代码语言:javascript
复制
@SerializedName("One&Two") // Ampersand not allowed in name
int OneTwo; //gives Invalid JSON response apparently

有人有更好的方法吗?

编辑工作的代码:

代码语言:javascript
复制
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课上,我有这样的:

代码语言:javascript
复制
@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中添加以下内容,我尝试了一种非常类似的方法:

代码语言:javascript
复制
public void RegisterValues( String [] Names, AsyncCallback<Map< String,Map<String, Integer>> callback); 

等等,确保Map<String, Map<String, Integer>>也在结构的onSucess()部分。然而,这导致了我的程序崩溃。在我看来它不喜欢嵌套的地图。但是,如果成员名与JSON字段匹配,GSON将在对象中自动解析。因此,我使用那个RegisterValues自动强制GSON解析这个。

堆栈跟踪:

代码语言:javascript
复制
   [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

这就是为什么我认为GSON不能使用AsyncCallback自动解析嵌套映射。更好的做法是让我的HTTP调用更符合下面的建议。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-27 19:04:03

最好的方法是将您发布的响应打包到一个类中。

代码语言:javascript
复制
{"id": 2, "result": {"FirstWorld": {"FirstValue": 5, ... }, "SecondWorld":{"FirstValue": 5, ....}}, "error":null }

代码语言:javascript
复制
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;
    }

}

我已经用这个测试过了,而且运行良好。

代码语言:javascript
复制
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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22637077

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档