gpt4 book ai didi

java - 在 XStream 中有更好的方法来编码/解码 JSON 和 Java 中的 List
转载 作者:塔克拉玛干 更新时间:2023-11-03 03:22:06 32 4
gpt4 key购买 nike

我正在使用 XStream和 JETTISON 的 Stax JSON 序列化程序,用于向 JSON javascript 客户端和 Java 网络应用程序发送/接收消息。

我希望能够创建一个对象列表以发送到服务器并正确编码到 Java 中,但 XStream 和 JSON 期望它采用的格式非常不直观,需要我们的 javascript 库来跳过箍。

[使用 GSON 编辑更新问题图书馆]我试图使用 GSON library但是当我只期望通用父类(super class)时它不能反序列化具体对象(XStream 和 Jettison 处理这个因为类型信息被烘焙到序列化中)。

GSON FAQ states Collection Limitation :

Collections Limitations

Can serialize collection of arbitrary objects but can not deserialize from it

Because there is no way for the user to indicate the type of the resulting object

While deserializing, Collection must be of a specific generic type

也许我使用了错误的 Java 实践,但我将如何构建一个 JSON 到 Java 的消息传递框架,以 JSON 格式发送/接收各种具体的 Message 对象?

例如这失败了:

public static void main(String[] args) {
Gson gson = new Gson();

MockMessage mock1 = new MockMessage();
MockMessage mock2 = new MockMessage();
MockMessageOther mock3 = new MockMessageOther();

List<MockMessage> messages = new ArrayList<MockMessage>();
messages.add(mock1);
messages.add(mock2);
messages.add(mock3);

String jsonString = gson.toJson(messages);

//JSON list format is non-intuitive single element array with class name fields
System.out.println(jsonString);
List gsonJSONUnmarshalledMessages = (List)gson.fromJson(jsonString, List.class);
//This will print 3 messages unmarshalled
System.out.println("XStream format JSON Number of messages unmarshalled: " + gsonJSONUnmarshalledMessages.size());
}

[{"val":1},{"val":1},{"otherVal":1,"val":1}]
Exception in thread "main" com.google.gson.JsonParseException: The JsonDeserializer com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter@638bd7f1 failed to deserialized json object [{"val":1},{"val":1},{"otherVal":1,"val":1}] given the type interface java.util.List

这是一个例子,我想发送一个包含 3 个 Message 对象的列表,其中 2 个是相同类型,第 3 个是不同类型。

import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;

class MockMessage {
int val = 1;
}
class MockMessageOther {
int otherVal = 1;
}

public class TestJSONXStream {


public static void main(String[] args) {
JettisonMappedXmlDriver xmlDriver = new JettisonMappedXmlDriver();
XStream xstream = new XStream(xmlDriver);

MockMessage mock1 = new MockMessage();
MockMessage mock2 = new MockMessage();
MockMessageOther mock3 = new MockMessageOther();

List messages = new ArrayList();
messages.add(mock1);
messages.add(mock2);
messages.add(mock3);

String jsonString = xstream.toXML(messages);

//JSON list format is non-intuitive single element array with class name fields
System.out.println(jsonString);
List xstreamJSONUnmarshalledMessages = (List)xstream.fromXML(jsonString);
//This will print 3 messages unmarshalled
System.out.println("XStream format JSON Number of messages unmarshalled: " + xstreamJSONUnmarshalledMessages.size());

//Attempt to deserialize a reasonable looking JSON string
String jsonTest =
"{"+
"\"list\" : ["+
"{"+
"\"MockMessage\" : {"+
"\"val\" : 1"+
"}"+
"}, {"+
"\"MockMessage\" : {"+
"\"val\" : 1"+
"}"+
"}, {"+
"\"MockMessageOther\" : {"+
"\"otherVal\" : 1"+
"}"+
"} ]"+
"};";

List unmarshalledMessages = (List)xstream.fromXML(jsonTest);

//We expect 3 messages but XStream only deserializes one
System.out.println("Normal format JSON Number of messages unmarshalled: " + unmarshalledMessages.size());
}

}

凭直觉,我希望 XStream JSON 从以下格式序列化(并能够正确反序列化):

{
"list" : [
{
"MockMessage" : {
"val" : 1
}
}, {
"MockMessage" : {
"val" : 1
}
}, {
"MockMessageOther" : {
"otherVal" : 1
}
} ]
}

相反,XStream 创建单个元素列表,其中包含以类名命名的字段和相同类型对象的嵌套数组。

{
"list" : [ {
"MockMessage" : [ {
"val" : 1
}, {
"val" : 1
} ],
"MockMessageOther" : {
"otherVal" : 1
}
} ]
}

问题可能是使用XStream XML引起的CollectionConverter

有没有人对允许您读/写任意 Java 对象的良好 JSON Java 对象序列化有建议?我看着 Jackson Java JSON Processor但是当您从流中读取对象时,您必须指定它与 XStream 不同的对象类型,它将读取任何对象(因为序列化的 XStream JSON 包含类名信息)。

最佳答案

我同意其他发帖人的观点,即 XStream 不太合适——它是一个 OXM(对象/Xml 映射器),并且 JSON 是使用 XML 处理路径作为辅助输出格式处理的。这就是为什么需要一个“约定”(关于如何将分层 xml 模型转换为 json 的对象图模型,反之亦然);而你的选择归结为使用任何对次优选择影响最小的东西。如果 XML 是您的主要数据格式,那么它工作正常,您只需要一些基本的 JSON(类似)支持。

为了获得良好的 JSON 支持,我会考虑使用一个 JSON 处理库来进行真正的 OJM 映射(我假设 Svenson 也这样做,但另外),例如:

此外:即使您确实需要同时支持 XML 和 JSON,IMO 最好为这些任务使用单独的库——在服务器端使用的对象(bean)不需要不同,只是序列化库可以转换到/从 xml 和 json。

关于java - 在 XStream 中有更好的方法来编码/解码 JSON 和 Java 中的 List<Object>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/836805/

32 4 0