Android - 改造 Gson - 如何解析 JSON 字符串到 JSON 响应中 JSON 键的对象?
Android - Retrofit Gson- How to parse JSON String to object at a JSON key in JSON response?
这是我的 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;
}
我想使用 Retrofit 和 GsonConvertor 将内容的值直接解析到我的内容模型对象中。但目前,我将其解析为字符串值,而不是使用 Gson.fromJson() 转换为我的内容模型对象。有什么解决方案可以达到我的预期结果吗?
当我以前使用 GsonConverterFactory 解析它时,Retrofit 在 onFailure 方法中给出了回调,但有这个异常:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 4 column 19 path $.data[0].content
希望你使用的是retrofit version 2.1.0,在这个版本中你可以选择你喜欢的解析器,但是在之前的版本中Gson是内置的解析器。我假设你需要使用 Gson。为此,您必须将 converterFactory
设置为 GsonConverterFactory
,示例如下。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
这会将 Gson 添加为您的 json 解析器。
查看 this tutorial. also read the documentation here。
不要忘记将此添加到您的 gradle
compile 'com.squareup.retrofit2:converter-gson:2.0.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;
}
问题出在 JSON 响应中,不在 correct JSON format 中。 "content"
字段应该是一个对象,而不是字符串:
{
"id": 2,
"name": "Test",
"content": {
"type": "status",
"text": "Lorem ipsum dummy text.",
"id": 1
}
}
这将允许 gson.fromJson(response, TestModel.class)
或带有 GsonConverterFactory
的 RetroFit
将您的响应正确解析为相应的对象。
当然,这仅适用于您有能力更改收到的 JSON 响应的情况。如果不是,首先要确保 控制响应的人知道他们这样做 是错误的。如果没有任何变化,那么您应该可以通过将 TestModel
中的 content
更改为 String
:
来解决此问题
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();
这是我的 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;
}
我想使用 Retrofit 和 GsonConvertor 将内容的值直接解析到我的内容模型对象中。但目前,我将其解析为字符串值,而不是使用 Gson.fromJson() 转换为我的内容模型对象。有什么解决方案可以达到我的预期结果吗?
当我以前使用 GsonConverterFactory 解析它时,Retrofit 在 onFailure 方法中给出了回调,但有这个异常:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 4 column 19 path $.data[0].content
希望你使用的是retrofit version 2.1.0,在这个版本中你可以选择你喜欢的解析器,但是在之前的版本中Gson是内置的解析器。我假设你需要使用 Gson。为此,您必须将 converterFactory
设置为 GsonConverterFactory
,示例如下。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
这会将 Gson 添加为您的 json 解析器。
查看 this tutorial. also read the documentation here。
不要忘记将此添加到您的 gradle
compile 'com.squareup.retrofit2:converter-gson:2.0.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;
}
问题出在 JSON 响应中,不在 correct JSON format 中。 "content"
字段应该是一个对象,而不是字符串:
{
"id": 2,
"name": "Test",
"content": {
"type": "status",
"text": "Lorem ipsum dummy text.",
"id": 1
}
}
这将允许 gson.fromJson(response, TestModel.class)
或带有 GsonConverterFactory
的 RetroFit
将您的响应正确解析为相应的对象。
当然,这仅适用于您有能力更改收到的 JSON 响应的情况。如果不是,首先要确保 控制响应的人知道他们这样做 是错误的。如果没有任何变化,那么您应该可以通过将 TestModel
中的 content
更改为 String
:
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();