如何在 C# 中反序列化由 JAVA 程序使用 jackson 发送的 JSON 对象
本文关键字:jackson 对象 JSON 程序 反序列化 JAVA | 更新日期: 2023-09-27 18:32:40
我正在做一个需要.NET程序和JAVA程序通过协议进行互操作的项目。
JAVA端使用 Jackson 来序列化简单的 JAVA 对象(导致 JSON-Packets 将具体类作为@class成员(。
但是 .NET 端对此使用不同的约定 - 此处的类型由__type成员指定。
我可以按摩 .NET 端以接受 JACKSON 格式的数据包吗?在 JAVA 端更改协议格式将是次优的,因为该协议已经在其他地方使用,因此最好让 .NET 适应。
目前,我正在查看.NET DataContractJsonSerializer - 但如果需要,也可以在.NET端使用第三方库。
JSON.NET 能提供这种灵活性吗?顺便说一句,像汇编版本这样的问题在这里不是问题,所以协议不发送该信息是完全可以的。
编辑以使我的意图更清晰,这里有一些示例代码:
爪哇端
package some.pkg;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)public abstract class EventBase {
public final String superField;
protected EventBase(final String superField) {
this.superField = superField;
}
}
第二个 JAVA 包类
package some.pkg;
public final class EventA extends EventBase {
public final int intFieldA;
public EventA(final int intFieldA, final String superField) {
super(superField);
this.intFieldA = intFieldA;
}
private EventA() {this(0,null);}//for jackson
}
杰克逊生成的 JSON
杰克逊生成的 JSON 字符串看起来像
{
"@class" : "some.pkg.EventA",
"superField" : "S1",
"intFieldA" : 1
}
。网
在这里我有等效的类(此处未显示的方法 - 这是一个请求/事件协议,请求方法存储在数据包本身中。
所以在这里我期待类似于
namespace some.pkg
{
public sealed class EventA extends EventBase {
public EventA(final int intFieldA, final String superField) : base(superField) {
this.intFieldA=intFieldA;
}
[DataMember]
public int fieldA { get; private set; }
}
。EventBase 的超类和其他子类被 elied。
对我来说,这里的问题是杰克逊通过@c或通过@class向班级发出信号的方式,而不是Microsoft的标准"__type"属性或JSON。NET的"$type"。
已编辑 - 摘要
好的,在 .NET 序列化程序之后切换$type与@class的答案确实很好(只要神奇的字符串@class和$type不在其他地方用作有效负载数据(。
看看 JSON。NET 的来源告诉我,$type decriminator 字段是一个 const 字符串,因此更改它需要我们使用修补的 JSON.NET 库,这看起来比在 JsonReader/Writer 类执行其操作之前更改违规字符串要多得多。
我不太确定转换 JSON.NET 的默认命名约定。但如果我是你,我会使用如下所示的"JSON 拦截器"函数
public static class JSONInterceptor {
public static string sanitizeJSON(string originalJSONFromJava)
{
//add any other validation checks here as you may see fit. ex: null checks
return originalJSONFromJava.replace("@class", "$type");
}
}
然后使用它来生成 .NET 类,如下所示
return JsonConvert.DeserializeObject<EventA>(JSONInterceptor.sanitizeJSON(originalJSONFromJava));
我自己还没有尝试过这个。 但这个想法是向你展示这也可以通过以下方式完成
JSON 是一种数据格式,适用于所有语言,即使您使用 Tex 生成 json 数据也是如此。
在.net中,反序列化json对象的最简单(恕我直言(方法是使用 Json.Net。
例:
爪哇端
public class A {
@JsonProperty("afield")
public String afield;
}
然后在 C# 中声明一个相等的类
public class A {
[JsonProperty("afield")]
public string afield {get;set;}
}
因此,当您从 java 端接收 json 对象 A 时,您只需要调用 JsonConvert.DeserializeObject<A>(stringreceived)
即可获取该对象。
等价物,适用于 JSON.net 和 JsonSubTypes的 C# 的杰克逊概念:
[JsonConverter(typeof(JsonSubtypes), "@class")]
[JsonSubtypes.KnownSubType(typeof(EventA), "some.pkg.EventA")]
public class EventBase {
}
在自述文件中查看更多可能性