【问题标题】:Can I have an Avro Schema with an enum that includes values as enum members?我可以拥有一个 Avro 架构,其枚举包含值作为枚举成员吗?
【发布时间】:2020-08-11 11:55:02
【问题描述】:

这是我要转换为 Avro Schema 的 Java 枚举:

public enum ApplicationCode {
    APP_A("MY-APP-A"),
    APP_B("MY-APP-B");


    private final String code;

    ApplicationCode(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }
}

由于枚举在 Avro 中通常可用作类型,因此我提出了以下建议:

{
  "type" : "enum",
  "name" : "ApplicationCode",
  "namespace" : "com.example",
  "symbols" : [ "APP_A", "APP_B" ]
}

并像这样在我的主要 Avro 中引用它:

"fields": [
    {
      "name": "masterApplicationCode",
      "type": "ApplicationCode"
    }, 

它就是这样工作的,但不幸的是,我使用这种方法丢失了应用程序代码(例如“MY-APP-A”)。我正在寻找一些东西,它允许我同时包含代码和标签。类似的东西

{
  "type" : "enum",
  "name" : "ApplicationCode",
  "namespace" : "com.example",
  "symbols" : [ "APP_A("MY-APP-A")", "APP_B("MY-APP-B")" ]
}

是否有可能拥有这种复杂的枚举,或者是否有任何解决方法来实现这一点?

【问题讨论】:

  • 您是否尝试过覆盖枚举中的 toString 方法?类似于 super.toString() + "('" + code + "')"
  • 如何覆盖 Avro 文件中的 toString() 方法? @SKumar

标签: java apache-kafka enums avro


【解决方案1】:

我相信 avro 架构在内部将其转换为 JSON 字符串。所以,我认为问题更多是关于序列化枚举。从这里参考 - https://www.baeldung.com/jackson-serialize-enums

如果你像这样使用 JsonFormat 注释,我认为它应该返回代码 -

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum ApplicationCode {

否则您将需要为枚举添加自定义序列化程序。

【讨论】:

  • 我像这样生成了 AvroSchema,并按照您的建议使用了 toString 覆盖:Schema avroSchema = ReflectData.get().getSchema(ApplicationCode.class); out.print(avroSchema.toString(true)); 但架构仍然看起来像这样:{ "type" : "enum", "name" : "ApplicationCode", "namespace" : "com.example", "symbols" : [ "APP_A", "APP_B" ] }
  • 感谢上面的例子,它启发了我编写自定义序列化器/反序列化器@SKumar
【解决方案2】:

我通过编写自定义序列化器/反序列化器解决了我的问题,该序列化器/解串器将具有复杂类型字段的对象映射到正在发送的对象,例如字符串而不是枚举。

这里是自定义序列化程序的示例:

public class CustomSerializer implements Serializer<ApplicationObject> {

    @Override
    public byte[] serialize(String topic, ApplicationObject ApplicationObjectDto) {
        com.example.avro.ApplicationObject applicationObject = com.example.avro.ApplicationObject.newBuilder()
                .setApplicationCode(ApplicationObjectDto.getApplicationCode().getCode())
                .build();
        return SerializationUtils.serialize(applicationObject);
    }
}

【讨论】:

    猜你喜欢
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    相关资源
    最近更新 更多