如何在 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 类执行其操作之前更改违规字符串要多得多。

如何在 C# 中反序列化由 JAVA 程序使用 jackson 发送的 JSON 对象

我不太确定转换 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 {
}

在自述文件中查看更多可能性