【问题标题】:Kotlin: Change the json property name depending on the @JsonViewKotlin:根据 @JsonView 更改 json 属性名称
【发布时间】:2019-05-09 16:18:24
【问题描述】:

我正在尝试使用 Jackson 以 2 种不同的方式序列化同一个 DTO 对象,具体取决于 @JsonView

我想为同一个字段使用 2 个不同的名称。在一种情况下,我想将 json 属性命名为 myField(就像类字段名称一样),在另一种情况下,我希望将其命名为 myInternalApiField

因此,我希望看到类似于以下所示的结果:

用法 1(外部 API 视图):

{
    "myField": "value1",
    "myOtherField": "otherValue"
}

用法 2(内部 API 视图):

{
    "myInternalApiField": "value1",
    "myOtherField": "otherValue"
}

在我的 Java 实现中,我使用了自定义 getter、setter 和 @JsonView 注释的组合,如下所示:

public class CustomDTO {
        @JsonView(Views.ExternalApiView)
        private String myField;
        // Other fields here

        @JsonView(Views.InternalApiView)
        public String getMyInternalApiField() { return myField; }
        @JsonView(Views.InternalApiView)
        public void setMyInternalApiField(String value) { this.myField = value; }

        @JsonView(Views.ExternalApiView)
        public String getMyField() { return myField; }

        @JsonView(Views.ExternalApiView)
        public void setMyField(String value) { this.myField = value }
}

但是我不知道如何在 Kotlin 中正确实现相同的结果。

我正在考虑使用类似的东西:

data class CustomDTO(
        @get:[JsonView(Views.ExternalApiView) JsonProperty("myField")]
        @get:[JsonView(Views.InternalApiView) JsonProperty("myInternalApiField")]
        @set:[JsonView(Views.InternalApiView) JsonProperty("myField")]
        @set:[JsonView(Views.InternalApiView) JsonProperty("myInternalApiField")]
        var myField: String,
        val myOtherField: String,
        val myDifferentField: String
)

但这在 Kotlin 中是不允许的。

您对如何在 Kotlin 中像在 Java 中一样使用 @JsonView 有什么建议吗?

【问题讨论】:

    标签: java serialization kotlin jackson deserialization


    【解决方案1】:

    怎么样:

    data class CustomDTO(
            @JsonView(ExternalApiView::class)
            var myField: String,
            val myOtherField: String,
            val myDifferentField: String
    ) {
        val myExternalField: String
            @JsonView(InternalApiView::class)
            get() {
                return myField
            }
    }
    

    看起来有些方法不需要在 DTO 中创建计算属性,例如:

    但是这些都有自己的复杂性,即使这种复杂性不在 DTO 类中。我不确定这些对是否更有吸引力,但你可以看看它们是否对你有吸引力。

    【讨论】:

    • 这似乎是一个可行的解决方案,但它不会在 CustomDTO 类中产生一个新字段,在序列化/反序列化过程之外也可见吗?我试图不引入新变量;)
    • 我认为它不会比您发布的 Java 版本引入更多的变量——上面 kotlin 版本中的 val 是派生值,没有额外的存储空间。它在序列化过程之外是可见的,但在 Java 版本中 getMyInternalApiField 也是如此,不是吗?
    • 你说服了我!让我稍等一下,看看这里是否会出现任何其他建议的解决方案,然后我会接受你的回答。非常感谢!
    • 我同意,如果有一种方法可以单独使用注释来做到这一点,那就太好了,尽管我不知道有什么方法可以做到这一点。 ;)
    猜你喜欢
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 2012-01-18
    • 2019-12-10
    相关资源
    最近更新 更多