【问题标题】:Jackson Unwrap / Wrap Object杰克逊展开/包裹对象
【发布时间】:2017-08-04 23:32:53
【问题描述】:

我有一个 spring boot 项目,我有一个这样的类:

@Value
public class A {
  @JsonUnwrapped
  OrderKey key;
  String description;
  B b;

  @Value
  public static class B {
    String description;
  }

}

@Value
public class OrderKey {
  @JsonProperty( "_key" )
  String id;

}

我有 mixins,但为简洁起见,在此示例中添加了注释。 这在序列化为 JSON 时效果很好,问题是当我尝试反序列化时,如果存在一些 @JsonWrapped 注释,它可能会起作用。

简而言之,我正在尝试将 ArangoDB 与 rest 一起使用,我可以创建/读取文档,但我需要使用自己的值对象,不幸的是我不能将密钥用作字符串,它由 @987654323 封装@。 @Value 注解来自 lombok 项目。

有什么办法可以做到吗?

【问题讨论】:

    标签: java jackson


    【解决方案1】:

    我最终在 mixin 本身内部进行序列化/反序列化,这样我可以避免 @JsonUnwrapped 注释和另一个用于 Key 的 mixin。

    混音:

    public class OrderMixin {
    
        @JsonDeserialize( using = OrderKeyDeserializer.class )
        @JsonSerialize( using = OrderKeySerializer.class )
        @JsonProperty( "_key" )
        OrderKey key;
    
        @JsonProperty( "description" )
        String description;
    
        @JsonProperty( "amount" )
        String amount;
    
        @JsonProperty( "operation" )
        Order.Operation operation;
    
        @JsonProperty( "creationDate" )
        LocalDateTime creationDate;
    
        public static class OrderKeySerializer extends JsonSerializer<OrderKey> {
    
            public OrderKeySerializer() {
                super( OrderKey.class );
            }
    
            @Override
            public void serialize( OrderKey value, JsonGenerator gen, SerializerProvider provider ) throws IOException {
                gen.writeString( value.getOrderId() );
            }
        }
    
        public static class OrderKeyDeserializer extends JsonDeserializer<OrderKey> {
    
            public OrderKeyDeserializer() {
                super( OrderKey.class );
            }
    
            @Override
            public OrderKey deserialize( JsonParser jsonParser, DeserializationContext context ) throws IOException {
                JsonNode node = jsonParser.getCodec().readTree( jsonParser );
    
                return OrderKey.get( node.asText() );
            }
        }
    
    }
    

    值对象:

    @Value
    public class Order implements Serializable {
    
      private static final long serialVersionUID = 901109456762331944L;
    
      OrderKey key;
    
      String description;
    
      String amount;
    
      Operation operation;
    
      LocalDateTime creationDate;
    
      @Value
      public static class Operation {
    
        String id;
    
        String description;
    
        String status;
    
        LocalDateTime creationDate;
      }
    
    }
    
    
    @Value
    public class OrderKey implements Serializable {
    
      private static final long serialVersionUID = -8102116676316181864L;
    
      private String orderId;
    
      public static OrderKey get( String orderId ) {
          return new OrderKey( orderId );
      }
    
    }
    

    【讨论】:

      【解决方案2】:

      您可以尝试在class A 中定义一个带有@JsonCreator 注释的构造函数。然后,Jackson 可以使用此构造函数创建一个 A 对象,并将您期望在 JSON 文档中的字段映射到 A 的字段。简化示例:

      @Value
      public class A {
          @JsonUnwrapped
          OrderKey key;
          String description;
      
          @JsonCreator
          public A(@JsonProperty("key") String key,
                   @JsonProperty("description") String description) {
              this.key = new OrderKey(key);
              this.description = description;
          }
      }
      

      请注意,A 的此构造函数将阻止创建 @Value 隐含的 @AllArgsConstructor 构造函数。

      Java 8 和一些额外的模块也可以避免构造函数注释。例如,检查this 我的其他答案。

      【讨论】:

        猜你喜欢
        • 2013-10-05
        • 2017-10-03
        • 2018-06-21
        • 1970-01-01
        • 2019-05-21
        • 2022-06-22
        • 1970-01-01
        • 1970-01-01
        • 2019-04-13
        相关资源
        最近更新 更多