【问题标题】:Change property names while deserialzing class to JSON in Spring MVC在 Spring MVC 中将类反序列化为 JSON 时更改属性名称
【发布时间】:2015-02-26 05:57:13
【问题描述】:

我正在尝试使用 Spring 使用以下 API 调用:

HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds);

HttpEntity<String> request = new HttpEntity<String>(headers);
RestTemplate restTemplate = new RestTemplate();

Item item = restTemplate.exchange(url, HttpMethod.GET, request, Item.class).getBody();

我从 API 得到的响应格式如下:

{    
"item":[{
    "itemname": "abc",
    "qty":...
}]
}

Item 类具有以下字段:

Class Item{
    @JsonProperty("itemname")
    String name;
    @JsonProperty("qty")
    int quantity;

    // Getter / setter methods
}

我在字段中添加了 JsonProperty 注释,因为它们的名称与我从 API 获得的 json 不同。有了这个,我能够成功地反序列化 api 响应。

但是,当我尝试再次将 Item 类序列化为 json 时,字段名称为“itemname”和“qty”。有什么方法可以将这些保留为“名称”和“数量”,但又能够映射到 API 响应?

提前致谢。

【问题讨论】:

  • 我认为您混淆了序列化和反序列化。当从外部表示中检索值时 - 它是反序列化,当保存在外部表示中时 - 它是序列化。

标签: spring resttemplate


【解决方案1】:
  1. 如果你只是想以不同的形式序列化,你可以这样做:

    public static class Item {
    
      private String name;
      private int quantity;
    
      @JsonProperty("name")
      public String getName() {
        return name;
      }
    
      @JsonProperty("itemname")
      public void setName(String name) {
        this.name = name;
      }
    
      @JsonProperty("quantity")
      public int getQuantity() {
        return quantity;
      }
    
      @JsonProperty("qty")
      public void setQuantity(int quantity) {
        this.quantity = quantity;
     }
    

    }

    这将读取 "{"itemname": "abc", "qty":10 }" 并写入 "{"name": "abc", "quantity":10 }"

    但是有一个很大的缺点 - 你将无法阅读 "{"name": "abc", "quantity":10 }",使用这个 ObjectMapper(这是更糟糕的解决方案)。

  2. 您可以使用 2 ObjectMappers 而不是 class Annotations 使用 Mixins,来配置特定的反序列化

    这就是你的 Mixin 的样子:

    abstract public static class ItemMixin {
        ItemMixin(@JsonProperty("itemname") String itemname, @JsonProperty("qty") int qty) { }
        // note: could alternatively annotate fields "w" and "h" as well -- if so, would need to @JsonIgnore getters
        @JsonProperty("itemname") abstract String getName(); // rename property
        @JsonProperty("qty") abstract int getQuantity(); // rename property
    }
    

    这里是如何在 ObjectMapper 中添加 Mixin。

    objectMapper.addMixIn(Item.class, ItemMixinA.class);
    

    所以如果你用 Mixin ObjectMapper 反序列化,用标准 ObjectMapper 序列化就没有问题了。

  3. 您可以为您的班级编写自定义JsonDeserialization

    对于具有少量字段的类很容易做到,但复杂性会随着字段数量的增加而成比例地增加。

【讨论】:

  • Spring 是否提供基于注释的解决方案,用于将一个类的某些属性映射到另一个类?只是为了提供一些背景信息,我正在编写一个用户调用的代理 api,然后我的 api 又调用 3rd 方 api 来获取一些数据。但是,第 3 方 api 提供了很多我用于后台计算的数据,但不想发送给用户。此外,与我想向用户展示的内容(我的原始问题)相比,第 3 方 api 中的密钥不同。这就是为什么我打算映射到一个新类(我在其中隐藏/更新属性)并将其发送给用户。
  • 如果要限制内部演示文稿的曝光,可以使用 Spring @Projections stackoverflow.com/questions/28447922/…
【解决方案2】:

尝试使用@JsonAlias 注解来指定可用于反序列化对象的其他属性名称。可以从这里获得更多信息: https://fasterxml.github.io/jackson-annotations/javadoc/2.9/com/fasterxml/jackson/annotation/JsonAlias.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    相关资源
    最近更新 更多