【问题标题】:Different @JsonProperty config for READ and WRITE on same field?同一字段上的 READ 和 WRITE 的不同 @JsonProperty 配置?
【发布时间】:2021-09-30 20:33:49
【问题描述】:

我有一个类(不能修改),比如

public class Standing {

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

反序列化时,我得到如下数据:

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

由于我无法修改 Standing 类,因此我有一个混合类:

@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;
}

由于收到的 json 没有 positionNumberpositionText 字段,我使用 @JsonPropery 注释。

对于Access.READ_ONLY,我只是忽略了positionNumber 字段。

positionText 字段上使用@JsonProperty(value = "position", access = JsonProperty.Access.WRITE_ONLY),我确保它在反序列化期间填充了来自json 的position 字段。

这在反序列化期间效果很好。

注意StandingSanitizer 设置positionNumber。这是因为接收到的position 值可以是非数字值,例如DSQ,在这种情况下positionNumber 字段将为null

但在序列化时,我想从 Standing 类中输出所有 3 个字段,例如:

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

但是由于positionText字段上的@JsonProperty(value = "position", access = JsonProperty.Access.WRITE_ONLY),不幸的是它没有被序列化。

理论上,我想做一些类似的事情:

@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;
}

我可以对 READ 和 WRITE 使用不同的 @JsonProperty 注释。

但这是不可能的,因为不允许在字段上重复 @JsonProperty 注释;据我所知,不支持可重复的注释。

有没有其他方法可以解决这个问题?

我能想到的一件事是有 2 个 ObjectMapper 实例,有 2 个不同的 StandingMixIns; 1 用于反序列化,1 用于序列化。但我更愿意继续拥有 1 个 ObjectMapper 实例,因此使用 2 将是最后的手段。

【问题讨论】:

    标签: java json jackson jackson-databind jackson-annotations


    【解决方案1】:

    感谢@Franjavi,您确实是对的,我应该在 getter/setter 上使用注释,而不仅仅是在字段上。我只专注于使用字段,因为我的混合类是用带有隐式 getter/setter 的 Groovy 编写的。

    我把班级精简了一点:

        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);
        }
    
    

    (完全删除positionText并使用抽象方法)

    【讨论】:

      【解决方案2】:

      您可以使用 getter 和 setter 来获得额外的自定义。 get 将充当 READ,set 将充当 WRITE。请注意,您不需要访问属性或字段级别注释:

          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;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-09
        • 1970-01-01
        相关资源
        最近更新 更多