Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/224.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用改装时手动解析响应的一部分_Android_Json_Gson_Retrofit - Fatal编程技术网

Android 使用改装时手动解析响应的一部分

Android 使用改装时手动解析响应的一部分,android,json,gson,retrofit,Android,Json,Gson,Retrofit,我正在使用一个RESTAPI,它返回一个JSON文档,该文档的开头如下,并包含一个带有字符串ID(如“ABC”)的项目“集合”。注意“routes”字段,它包含一系列名为“ABC”、“ABD”、“ABE”等字段,但是在json中routes没有表示为数组,所以所有这些 { "status":true, "page":1, "per_page":500, "total_count":1234, "total_pages":8, "total_on_page":500, "routes":{

我正在使用一个RESTAPI,它返回一个JSON文档,该文档的开头如下,并包含一个带有字符串ID(如“ABC”)的项目“集合”。注意“routes”字段,它包含一系列名为“ABC”、“ABD”、“ABE”等字段,但是在json中routes没有表示为数组,所以所有这些

{
"status":true,
"page":1,
"per_page":500,
"total_count":1234,
"total_pages":8,
"total_on_page":500,
"routes":{
    "ABC":[
    {
        "value":22313,
        <......>
{
“状态”:正确,
“页码”:1,
“每页”:500,
“总计数”:1234,
“总页数”:8页,
“第页总计”:500,
“路线”:{
“ABC”:[
{
“价值”:22313,
我使用的是改型,问题是routes字段不是数组(尽管从概念上讲确实是)而改型/Gson要求我为带有字段变量abc、abd等的路由创建一个模型对象-随着数据的变化,这是不实际的。由于各种原因,更改服务器API很困难,因此我希望在Android客户端上解决这一问题

我认为有以下几种选择:

  • 在JSON文档到达Gson之前拦截它并调整文档,可能使用定制的Gson解析器,或者通过拦截HTTP响应

  • 绕过JSON解析,从改造中获取JSON文档(我还没有弄清楚如何做到这一点,或者如果可能的话)

  • 使用一些我不知道的改进功能将字段名映射到集合


我非常感谢您的帮助,特别是如果有一种快速简便的方法来解决这个问题。

调用RestService后,不要使用模型名称作为参数,您必须使用来自改装库的Default
Response

RestService方法

@FormUrlEncoded
    @POST(GlobalVariables.LOGIN_URL)
    void Login(@Field("email") String key, @Field("password") String value, Callback<Response> callback);
@FormUrlEncoded
@POST(GlobalVariables.LOGIN\uURL)
无效登录(@Field(“email”)字符串键、@Field(“密码”)字符串值、回调);
在活动中调用方法

getService().Login(email, password, new MyCallback<Response>(context, true, null)
{
    @Override
    public void failure(RetrofitError arg0)
     {
        // TODO Auto-generated method stub
        UtilitySingleton.dismissDialog((BaseActivity<?>) context);
        System.out.println(arg0.getResponse());
      }

    @Override
    public void success(Response arg0, Response arg1)
    {
         String result = null;
         StringBuilder sb = null;
         InputStream is = null;
         try
         {
                is = arg1.getBody().in();
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null)
                {
                    sb.append(line + "\n");
                    result = sb.toString();
                    System.out.println("Result :: " + result);
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    });
getService().Login(电子邮件、密码、新MyCallback(上下文、true、null)
{
@凌驾
公共无效失败(错误arg0)
{
//TODO自动生成的方法存根
实用程序Singleton.dismissDialog((BaseActivity)上下文);
System.out.println(arg0.getResponse());
}
@凌驾
公共作废成功(响应arg0、响应arg1)
{
字符串结果=null;
StringBuilder sb=null;
InputStream=null;
尝试
{
is=arg1.getBody().in();
BufferedReader reader=新的BufferedReader(新的InputStreamReader(is));
sb=新的StringBuilder();
字符串行=null;
而((line=reader.readLine())!=null)
{
sb.追加(第+行“\n”);
结果=sb.toString();
System.out.println(“结果::”+Result);
}
}
捕获(例外e)
{
e、 printStackTrace();
}
}
});

事实证明,在默认情况下,改型对Gson的使用使得添加自定义反序列化程序来处理JSON文档中出现问题的部分相当容易

RestAdapter restAdapter = new RestAdapter.Builder()
        .setEndpoint(ApiDefinition.BASE_URL)
        .setConverter(getGsonConverter())
        .build();

public Converter getGsonConverter() {
    Gson gson = new GsonBuilder()
            .registerTypeAdapter(RouteList.class, new RouteTypeAdapter())
            .create();
    return  new GsonConverter(gson);
}


public class RouteTypeAdapter implements JsonDeserializer<RouteList> {
    @Override
    public RouteList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        Gson gson = new Gson();
        RouteList routeList = new RouteList();
        JsonObject jsonObject = json.getAsJsonObject();
        for (Map.Entry<String,JsonElement> elementJson : jsonObject.entrySet()){
            RouteList wardsRoutes = gson.fromJson(elementJson.getValue().getAsJsonArray(), RouteList.class);
            routeList.addAll(wardsRoutes);
        }
        return routeList;
    }

}
RestAdapter RestAdapter=new RestAdapter.Builder()
.setEndpoint(ApiDefinition.BASE_URL)
.setConverter(getGsonConverter())
.build();
公共转换器getGsonConverter(){
Gson Gson=new GsonBuilder()
.registerTypeAdapter(RouteList.class,新RouteTypeAdapter())
.create();
返回新的GsonConverter(gson);
}
公共类RouteTypeAdapter实现JsonDeserializer{
@凌驾
公共RouteList反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)引发JsonParseException{
Gson Gson=新的Gson();
RouteList RouteList=新的RouteList();
JsonObject JsonObject=json.getAsJsonObject();
for(Map.Entry elementJson:jsonObject.entrySet()){
RouteList wardsRoutes=gson.fromJson(elementJson.getValue().getAsJsonArray(),RouteList.class);
路线列表。添加所有(前进路线);
}
返回路线图;
}
}

编写反序列化程序要干净得多。此外,解析也在后台线程上完成,这与您的方法不同。:)我已经寻找了这么久……这是一种干净的方法,谢谢!什么是ApiDefinition.BASE\u URL?