解析包含基元和对象的JSONArray [英] Parse JSONArray which contains primitive and objects
问题描述
我有JSON响应,如下所示:
{
response:[
一些数字(例如8091),
{
在第一个JSONObject
},
{
中的一群原语在第二个JSONObject
,
{
第三个JSONObject中的原语
},
...(等等)
所以它是一个带有第一个整数元素的数组,其他元素是JSONObject。
我不需要整数元素来解析。那么如何使用GSON来处理它呢?
解决方案我会通过创建一个自定义的 JsonDeserializer来解决这个问题
并在解析之前将其注册到您的 Gson
实例。这个自定义反序列化器将被设置为处理 int
和真实对象。
首先,你需要建立一系列模型对象来表示数据。下面是一个可能的样板:
私有静态类TopLevel {
@SerializedName( 响应)
private final List< ResponseElement>要素;
私人TopLevel(){
this.elements = null;
private static class ResponseInteger implements ResponseElement {
private final int value;
public ResponseInteger(int value){
this.value = value;
private static class ResponseObject实现ResponseElement {
@SerializedName(id)
private final String id;
@SerializedName(text)
private final String text;
private ResponseObject(){
this.id = null;
this.text = null;
private interface ResponseElement {
// marker interface
}
$ b TopLevel
和 ResponseObject
具有私有构造函数,因为它们会去让Gson使用反射设置它们的字段,而 ResponseInteger
具有一个公共构造函数,因为我们将从我们的自定义解串器手动调用它。
显然你必须填写 ResponseObject
和其余字段。
解串器相对简单。你发布的json只包含两种元素,我们将利用它。每次调用反序列化器时,它都会检查该元素是否为基元,并且如果是(或 ResponseObject $ c $),则返回 ResponseInteger
如果没有)。
private static class ResponseElementDeserializer实现JsonDeserializer< ResponseElement> {
@Override
public ResponseElement deserialize(JsonElement json,Type typeOfT,JsonDeserializationContext context)抛出JsonParseException {
if(json.isJsonPrimitive()){
return new ResponseInteger(json.getAsInt());
}
else {
return context.deserialize(json,ResponseObject.class);
要使用这个反序列化器,必须使用 GsonBuilder
对象在Gson上注册它。 私有静态Gson getGson(){
返回新的GsonBuilder()
.registerTypeAdapter(ResponseElement.class,新的ResponseElementDeserializer())
.create();
}
就是这样。现在,您可以使用 Gson
对象轻松解析 TopLevel
对象!
public void parseJson(){
TopLevel t = getGson()。fromJson(json,TopLevel.class); (ResponseElement元素:t.elements){
System.out.println(element);
}
}
8061
[450602:Поздравляем!]
[451700:СреакциейчатаирассуждениямиПапанипослерипа..]
[451578:Помним...Любим...Скорбим ...< br> 2107забираетлучших]
[451371:Землятебепухомбратишка]
[451332:Доигрался,минус900экзов< br>< br> RIP]
[451269 :]
[451242:https://www.twitch.tv/arthasподрубка< br>< br> evilpapech.ru - скидка30%нафутболки!]
[451217:]
[451181:илитакцежерстко?]
[451108:]
我使用了这些 toString()
方法,为简洁起见我省略了这些方法:
@Override
public String toString(){
return Integer.toString(value);
}
@Override
public String toString(){
return[+ id +:+ text +];
}
I have JSON response which looks like that:
{
"response":[
"Some number (for example 8091)",
{
"Bunch of primitives inside the first JSONObject"
},
{
"Bunch of primitives inside the second JSONObject"
},
{
"Bunch of primitives inside the third JSONObject"
},
... (and so on)
]
}
So it's an array with first integer element and other elements are JSONObject.
I don't need integer element to be parsed. So how do I handle it using GSON?
解决方案 I would solve this problem by creating a custom JsonDeserializer
and registering it to your Gson
instance before parsing. This custom deserializer would be set up to handle both int
s and real objects.
First you need to build up a series of model objects to represent the data. Here's a template for what that might look like:
private static class TopLevel {
@SerializedName("response")
private final List<ResponseElement> elements;
private TopLevel() {
this.elements = null;
}
}
private static class ResponseInteger implements ResponseElement {
private final int value;
public ResponseInteger(int value) {
this.value = value;
}
}
private static class ResponseObject implements ResponseElement {
@SerializedName("id")
private final String id;
@SerializedName("text")
private final String text;
private ResponseObject() {
this.id = null;
this.text = null;
}
}
private interface ResponseElement {
// marker interface
}
TopLevel
and ResponseObject
have private constructors because they are going to let Gson set their fields using reflection, while ResponseInteger
has a public constructor because we're going to manually invoke it from our custom deserializer.
Obviously you will have to fill out ResponseObject
with the rest of its fields.
The deserializer is relatively simple. The json you posted contains only two kinds of elements, and we'll leverage this. Each time the deserializer is invoked, it checks whether the element is a primitive, and returns a ResponseInteger
if so (or a ResponseObject
if not).
private static class ResponseElementDeserializer implements JsonDeserializer<ResponseElement> {
@Override
public ResponseElement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonPrimitive()) {
return new ResponseInteger(json.getAsInt());
}
else {
return context.deserialize(json, ResponseObject.class);
}
}
}
To use this deserializer, you'll have to register it with Gson using the GsonBuilder
object.
private static Gson getGson() {
return new GsonBuilder()
.registerTypeAdapter(ResponseElement.class, new ResponseElementDeserializer())
.create();
}
And that's it. Now you can use this Gson
object to easily parse TopLevel
objects!
public void parseJson() {
TopLevel t = getGson().fromJson(json, TopLevel.class);
for (ResponseElement element : t.elements) {
System.out.println(element);
}
}
8061
[450602: Поздравляем!]
[451700: С реакцией чата и рассуждениями Папани после рипа..]
[451578: Помним...Любим...Скорбим...<br>2107 забирает лучших]
[451371: Земля тебе пухом братишка]
[451332: Доигрался, минус 900 экзов<br><br>R I P]
[451269: ]
[451242: https://www.twitch.tv/arthas подрубка<br><br>evilpapech.ru - скидка 30% на футболки!]
[451217: ]
[451181: или так це жерстко?]
[451108: ]
I used these toString()
methods, which I omitted above for brevity:
@Override
public String toString() {
return Integer.toString(value);
}
@Override
public String toString() {
return "[" + id + ": " + text + "]";
}
这篇关于解析包含基元和对象的JSONArray的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!