简体   繁体   English

在同一字段上读取和写入的不同@JsonProperty 配置?

[英]Different @JsonProperty config for READ and WRITE on same field?

I have a class (which cannot be modified) like我有一个 class(不能修改)像

public class Standing {

    private Integer positionNumber;
    private String positionText;
    private BigDecimal points;
    ..
}

When deserializing I get data like:反序列化时,我得到如下数据:

{
    "position": "1",
    "points": 10
}

As I cannot modify the Standing class I have a mix-in like:由于我无法修改Standing class 我有一个混合像:

@JsonDeserialize(converter = StandingSanitizer.class)
public abstract class StandingMixIn {

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    Integer positionNumber;

    @JsonProperty(value = "position", access = JsonProperty.Access.WRITE_ONLY)
    String positionText;
}

As the received json does not have positionNumber and positionText fields I use the @JsonPropery annotations.由于收到的 json 没有positionNumberpositionText字段,我使用了@JsonPropery注释。

With Access.READ_ONLY I simply ignore the positionNumber field.使用Access.READ_ONLY我只是忽略了positionNumber字段。

And with @JsonProperty(value = "position", access = JsonProperty.Access.WRITE_ONLY) on the positionText field I make sure it's populated with the position field from the json during deserialization.positionText字段上使用@JsonProperty(value = "position", access = JsonProperty.Access.WRITE_ONLY)我确保它在反序列化期间填充了 json 中的position字段。

This works well during deserialization.这在反序列化过程中效果很好。

Note the StandingSanitizer sets the positionNumber .注意StandingSanitizer设置了positionNumber This as the received position value can be non-number values like DSQ in which case the positionNumber field will be null .这是因为收到的position值可以是非数字值,如DSQ ,在这种情况下, positionNumber字段将为null

But when serializing I want to output all 3 fields from the Standing class like:但是在序列化时,我想要 output Standing class 中的所有 3 个字段,例如:

{
    "positionText": "1",
    "positionNumber": 1,
    "points": 10
}

But because of @JsonProperty(value = "position", access = JsonProperty.Access.WRITE_ONLY) on the positionText field it is not serialized unfortunately.但是由于positionText字段上的@JsonProperty(value = "position", access = JsonProperty.Access.WRITE_ONLY)不幸的是它没有被序列化。

In theory I would like to do have something like:从理论上讲,我想做类似的事情:

@JsonDeserialize(converter = StandingSanitizer.class)
public abstract class StandingMixIn {

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    Integer positionNumber;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    @JsonProperty(value = "position", access = JsonProperty.Access.WRITE_ONLY)
    String positionText;
}

where I could use different @JsonProperty annotation for both READ and WRITE.我可以在其中对 READ 和 WRITE 使用不同的@JsonProperty注释。

But this is not possible as duplicate @JsonProperty annotations on a field are not allowed;但这是不可能的,因为不允许在字段上重复@JsonProperty注释; and as far as I could see there is no support for repeatable annotations.据我所知,不支持可重复注释。

Is there any other solution to solve this?还有其他解决方案可以解决这个问题吗?

One thing I can think of is to have 2 ObjectMapper instances, with 2 different StandingMixIns ;我能想到的一件事是有 2 个ObjectMapper实例,有 2 个不同的StandingMixIns 1 for deserializing and 1 for serializing. 1 个用于反序列化,1 个用于序列化。 But I would prefer to keep having 1 ObjectMapper instance, so using 2 would be a last resort.但我更愿意保留 1 个ObjectMapper实例,因此使用 2 是最后的选择。

Thanks @Franjavi, you are indeed right I should use annotations on the getters/setters and not on the field only.谢谢@Franjavi,你确实是对的,我应该在 getters/setters 上使用注释,而不仅仅是在字段上。 I was to focussed on only using the fields as my mix-in classes are written in Groovy with implicit getters/setters.我只专注于使用字段,因为我的混合类是用隐式 getter/setter 在 Groovy 中编写的。

I slimmed down the class a bit more to just:我将 class 精简为:

    public abstract class StandingMixIn {

        @JsonProperty(access = JsonProperty.Access.READ_ONLY)
        Integer positionNumber;
        
        @JsonProperty(value = "positionText")
        public abstract String getPositionText();

        @JsonProperty(value = "position")
        public abstract void setPositionText(String positionText);
    }

(removing the positionText completely and using abstract methods) (完全删除positionText并使用抽象方法)

You could use the getters and setters to get that extra customization.您可以使用 getter 和 setter 来获得额外的定制。 The get will act as READ and the set as WRITE. get 将充当 READ,set 将充当 WRITE。 Note that you don't need the access properties or the field level annotation:请注意,您不需要访问属性或字段级注释:

    public abstract class StandingMixIn {
        @JsonProperty(access = JsonProperty.Access.READ_ONLY)
        Integer positionNumber;
        
        // No annotation on the field
        String positionText;

        @JsonProperty(value = "positionText")
        public String getPositionText() {
            return positionText;
        }

        @JsonProperty(value = "position")
        public void setPositionText(String positionText) {
            this.positionText = positionText;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM