我已经尝试了所有方法,但是解决方案非常丑陋,我真的想要一个直接的答案,是否可以改进(这意味着是否需要使用其他实现)。
问题在于带有GSON的Map of Maps:
根据Firebug给我以下回应:
{"id": 2, "result": {"FirstWorld": {"FirstValue": 5, ... }, "SecondWorld":{"FirstValue": 5, ....}}, "error":null }
大约有200个"Values",但是只有两个"Worlds"。到目前为止,这是我在ControlService课堂上要解析的内容:
"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解析它。
Map<String, Map<String, Integer>>
onSucess()
RegisterValues
堆栈跟踪:
[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调用。
最好的方法是将您发布的响应包装到一个类中。
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>用此类替换result,可能是extended Map。
Map<String, Integer>
Map