2016-09-06 52 views
4

这是我的JSON响应:Android - Retrofit Gson-如何解析JSON字符串以JSON响应中的JSON键对象?

{ 
     "id": 2, 
     "name": "Test", 
     "content": "{\"type\": \"status\", \"text\": \"Lorem ipsum dummy text.\", \"id\": 1}" 
} 

这些模型的结构:

class TestModel { 
    public int id; 
    public String name; 
    public Content content; 
} 

class Content { 
    public int id; 
    public String status; 
    public String text; 
} 

我想直接解析内容的价值将使用改装和GsonConvertor我的内容模型对象。但目前,我将它解析为字符串值,而不是使用Gson.fromJson()转换为我的内容模型对象。有没有解决方案来获得我的预期结果?

当我用用GsonConverterFactory解析它,改造给出onFailure处方法回调与此异常:

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 4 column 19 path $.data[0].content 
+0

直接通过模型类的改装 –

+0

@ColdFire:我这样做,但我想字符串值直接转换到我的内容模型。作为回应,我在内容密钥上获得了字符串值。 – MA13

+0

为什么响应中的“content”值是一个字符串?这不符合JSON标准,这就是为什么在你的'Retrofit'实例中添加一个'GsonConverterFactory'并不能给你想要的结果。正确的JSON格式会将“内容”作为JSON对象返回,而不是字符串。你有任何控制JSON响应? – Bryan

回答

3

的问题是使用JSON的回应这一点,是不是在correct JSON format。该"content"场应该是一个对象,而不是字符串:

{ 
    "id": 2, 
    "name": "Test", 
    "content": { 
     "type": "status", 
     "text": "Lorem ipsum dummy text.", 
     "id": 1 
    } 
} 

这将使要么gson.fromJson(response, TestModel.class)RetroFitGsonConverterFactory正确解析您的回复到相应的对象。


当然,这只适用于如果您有能力更改您收到的JSON响应。如果没有,首先确保在控制响应中的人知道他们正在做它错误。如果没有什么变化,那么你应该能够在TestModel解决此通过改变contentString

class TestModel { 
    public int id; 
    public String name; 
    public String content; 
} 

class Content { 
    public int id; 
    public String type; 
    public String text; 
} 

然后解析每个单独的对象:

TestModel testModel = gson.fromJson(response, TestModel.class); 
Content content = gson.fromJson(testModel.content, Content.class); 

如果响应不能另一种选择是为您的Content对象创建一个TypeAdapter

public class ContentAdapter extends TypeAdapter<Content> { 

    @Override 
    public void write(JsonWriter out, Content value) throws IOException { 
     // TODO: Writer implementation 
    } 

    @Override 
    public Content read(JsonReader in) throws IOException { 
     if(in.peek() != JsonToken.NULL) { 
      return fromJson(in.nextString()); 
     } else { 
      in.nextNull(); 
      return null; 
     } 
    } 

} 

然后添加TypeAdapter您GSON实现:

Gson gson = new GsonBuilder() 
     .registerTypeAdapter(Content.class, new ContentAdapter()).create(); 
+0

答案是正确的。服务器端的人不想为“Content”创建另一个表。所以,他以字符串格式存储这个值。这是主要问题,内容密钥的值是JSON字符串。现在,我将这个字符串转换为Content内容对象,如Content content = gson.fromJson(testModel.content,Content.class);'但我希望它能够在改进响应解析中通过GsonConverterFactory进行转换。我不想用'gson.fromJson()'来转换它。 – MA13

+0

@ MA13 JSON格式肯定是*不正确。即使“内容”存储为“字符串”,该“字符串”应该被序列化为JSON对象,而不是“字符串”。我不知道响应API是用什么语言编写的,但假设它是PHP;服务器端应该在将它传递给最终被编码的数组之前调用'json_decode(content)'。 – Bryan

+0

我无法对答复做任何事情。我想要一个解决方案或在Android端进行破解, – MA13

0

希望您使用的改装版本2.1.0,在这个版本中,您可以选择的解析器您但是在之前的版本中,Gson是内置的解析器。我假设你需要使用Gson。因此,您必须将converterFactory设置为GsonConverterFactory,下面给出示例。

Retrofit retrofit = new Retrofit.Builder() 
    .baseUrl("https://api.github.com") 
    .addConverterFactory(GsonConverterFactory.create()) 
    .build(); 

这将添加Gson作为你的json解析器。

检出this教程。还请阅读文档here

不要忘了在你的gradle这个

compile 'com.squareup.retrofit2:converter-gson:2.0.2' 
+0

是的,我正在使用改进版本2.1.0和GsonConverterFactory。它将返回内容键值作为字符串,而不是我的内容模型对象。而当我用于解析我的内容模型对象时,它会发出异常。我已经更新了我的问题,例外。顺便说一句,为什么在使用'com.squareup.retrofit2:converter-gson:2.0.2'时添加'com.google.code.gson:gson:2.6.2'作为依赖关系? – MA13

+0

也粘贴您的服务器响应 – droidev

+0

响应无例外或异常? – MA13

-2
import java.util.ArrayList; 
    import java.util.List; 
    import org.json.JSONArray; 
    import org.json.JSONException; 
    import org.json.JSONObject; 

    public class Parser { 
     public static List<TestModel> JsonParser(String JsonString) { 
      try { 
       JSONArray array = new JSONArray(content); 
       List<TestModel > arrayList = new ArrayList(); 
       for (int i = 0; i < array.length(); i++) { 
        JSONObject obj = array.getJSONObject(i); 
        TestModel model = new TestModel(); 
        model.setId(Integer.parseInt(obj.getString("id"))); 
        model.setName(obj.getString("name")); 


    JSONArray contentArray = newJSONArray(obj.getString("content"))); 
         JSONObject obj1 = contentArray.getJSONObject(1); 
         Content content = new Content(); 

         content.setId(Integer.parseInt(obj1.getString("id"))); 
         content.setStatus(obj1.getString("status")); 
         content.setText(obj1.getString("text")); 


        model.setContent(content); 
        arrayList.add(model); 
       } 
       return arrayList; 
      } catch (JSONException e) { 
       e.printStackTrace(); 
       return null; 
      } 
     } 
    } 
    class TestModel { 
//Generate Setter Getter for all properties 
    public int id; 
    public String name; 
    public Content content; 
} 

class Content { 
//Generate Setter Getter for all properties 
    public int id; 
    public String status; 
    public String text; 
} 
+0

我不希望这种机制。我正在使用GsonConverterFactory进行改进。所以,我需要一个使用两个库的机制,而不是直接使用JsonObject或JsonArray类。 – MA13