Java 如何使用GSON反序列化数据不存在的对象';是否没有成员/参数名称?

Java 如何使用GSON反序列化数据不存在的对象';是否没有成员/参数名称?,java,json,gson,Java,Json,Gson,API 为了反序列化响应,jsonschema2pojo.org创建了类OrderBook,如下所示: { "lastUpdateId": 1027024, "bids": [ [ "4.00000000", "431.00000000", [] ] ], "asks": [ [ "4.00000200", "12.000

API

为了反序列化响应,jsonschema2pojo.org创建了类OrderBook,如下所示:

{
    "lastUpdateId": 1027024,
    "bids": [
        [
            "4.00000000",
            "431.00000000", []
        ]
    ],
    "asks": [
        [
            "4.00000200",
            "12.00000000", []
        ]
    ]
}
公共类订单簿{
@SerializedName(“lastUpdateId”)
公共长假;
@序列化名称(“投标”)
公共列表投标=空;
@序列化名称(“asks”)
公共列表asks=null;
}
但是,您可以看到
列表
不正确

它应该类似于
List

但是,如果没有成员名称,这似乎是不可能的。如果GSON有一个标识位置而不是名称的注释,那就太好了。但这样的注释并不存在

从这种最简单的响应中获得POJO的正确方法是什么?

您不能使用
List
,因为内部列表的第三个索引是数组/List,而不是字符串


因此,在您的情况下,您应该使用
列表
好吧,如果您包含给定有效负载的。 它至少会给出一些关于有效负载中编码内容的更多提示:

{
“lastUpdateId”:1027024,
“投标书”:[
[
“4.00000000”,//价格
“431.00000000”,//数量
[//忽略。
]
],
“问”:[
[
"4.00000200",
"12.00000000",
[]
]
]
}
接下来,jsonschema2pojo生成的映射太幼稚,无法创建类型适配器,而类型适配器通常是唯一可以处理此类有效负载的工具。 例如:

下面的映射可以很容易地用Java反射反序列化,因为您可能不会更改它的状态,所以可以将它的所有字段设置为final

最终课程顺序{
final long lastUpdateId=long.valueOf(0);//如果为'0',则javac在任何地方都内联0
//所以我们有点作弊
最终投标清单=空;
最终列表asks=null;
@凌驾
公共字符串toString(){
返回MoreObjects.toStringHelper(此)
.add(“lastUpdateId”,lastUpdateId)
.添加(“投标”,投标)
.add(“询问”,询问)
.toString();
}
}
下面的对象需要一种稍微不同的方法来实例化反序列化的值。 它可能像前面的映射一样缺少构造函数(需要一个流到一个特殊结构的JSON树转换,然后用Java反射进行转换),但是手工实例化它更容易

最终类价格和数量{
最终双倍价格;
最终双倍数量;
私人价格和数量(最终双倍价格、最终双倍数量){
这个价格=价格;
这个。数量=数量;
}
静态价格和数量(最终双倍价格、最终双倍数量){
返回新的价格和数量(价格、数量);
}
@凌驾
公共字符串toString(){
返回MoreObjects.toStringHelper(此)
.添加(“价格”,价格)
.添加(“数量”,数量)
.toString();
}
}
现在,您可以告诉Gson如何从这样的JSON流反序列化上面的类实例

最终类价格和QuantityTypeAdapter
扩展类型适配器{
私有静态最终类型适配器实例=新价格和数量类型适配器()
.nullSafe();
私有价格和数量类型适配器(){
}
静态类型适配器get(){
返回实例;
}
@凌驾
公共作废写入(最终JsonWriter out、最终价格和数量值){
抛出新的UnsupportedOperationException();
}
@凌驾
读取公共价格和数量(最终JsonReader in)
抛出IOException{
in.beginArray();
final double price=in.nextDouble();//在文档中表示为价格
最终双倍数量=in.nextDouble();//在文档中表示为数量
//在.skipValue()中开始替换
//JsonReader.skipValue使用任何JSON文本,
//但在这里,我们明确地断言了一个[和]序列
in.beginArray();
in.endArray();
//结束in.skipValue()的替代项
in.endArray();
退货价格和数量(价格、数量);
}
}
private static final Gson Gson=new GsonBuilder()
.registerTypeAdapter(PriceAndQuantity.class,PriceAndQuantityTypeAdapter.get())
.create();
公共静态void main(最终字符串…参数)
抛出IOException{
//它只是从一个资源包中读取您在问题中输入的JSON
try(final-JsonReader-JsonReader=Resources.getPackageResourceJsonReader(Q50317182.class,“response.json”)){
final Order=gson.fromJson(jsonReader,Order.class);
系统输出打印项次(订单);
}
}
以下是一个示例输出:

订单{lastUpdateId=1027024,出价=[PriceAndQuantity{price=4.0,quantity=431.0}],询价=[PriceAndQuantity{price=4.000002,quantity=12.0}]


没有所谓的
列表
<代码>列表只有一个通用变量。您可能需要类似于
List
的东西,或者编写您自己的自定义反序列化程序。您需要为我们提供所有不同情况的响应,以设计精确的POJO映射。这是可行的,但这意味着必须为任何想在改造中使用此功能的人提供object fieldsquick提示;代码类似于
new reformation.Builder().addConverterFactory(GsonConverterFactory.create)(new GsonBuilder().registerTypeAdapter(PriceAndQuantity.class,PriceAndQuantityTypeAdapter.get()).create())
{
    "lastUpdateId": 1027024,
    "bids": [
        [
            "4.00000000",
            "431.00000000", []
        ]
    ],
    "asks": [
        [
            "4.00000200",
            "12.00000000", []
        ]
    ]
}
public class OrderBook {

@SerializedName("lastUpdateId")
public Long lastUpdateId;

@SerializedName("bids")
public List<List<String>> bids = null;

@SerializedName("asks")
public List<List<String>> asks = null;

}