如何使用 Jackson 注释将嵌套值映射到属性?

新手上路,请多包涵

假设我正在调用一个 API,该 API 响应产品的以下 JSON:

 {
  "id": 123,
  "name": "The Best Product",
  "brand": {
     "id": 234,
     "name": "ACME Products"
  }
}

我可以使用 Jackson 注释很好地映射产品 ID 和名称:

 public class ProductTest {
    private int productId;
    private String productName, brandName;

    @JsonProperty("id")
    public int getProductId() {
        return productId;
    }

    public void setProductId(int productId) {
        this.productId = productId;
    }

    @JsonProperty("name")
    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }
}

然后使用 fromJson 方法创建产品:

   JsonNode apiResponse = api.getResponse();
  Product product = Json.fromJson(apiResponse, Product.class);

但现在我想弄清楚如何获取品牌名称,这是一个嵌套属性。我希望这样的事情会起作用:

     @JsonProperty("brand.name")
    public String getBrandName() {
        return brandName;
    }

但当然没有。有没有一种简单的方法可以使用注释来完成我想要的?

我尝试解析的实际 JSON 响应非常复杂,我不想为每个子节点创建一个全新的类,即使我只需要一个字段。

原文由 kenske 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 471
2 个回答

你可以这样实现:

 String brandName;

@JsonProperty("brand")
private void unpackNameFromNestedObject(Map<String, String> brand) {
    brandName = brand.get("name");
}

原文由 Jacek Grobelny 发布,翻译遵循 CC BY-SA 3.0 许可协议

这就是我处理这个问题的方式:

Brand 类:

 package org.answer.entity;

public class Brand {

    private Long id;

    private String name;

    public Brand() {

    }

    //accessors and mutators
}

Product 类:

 package org.answer.entity;

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonSetter;

public class Product {

    private Long id;

    private String name;

    @JsonIgnore
    private Brand brand;

    private String brandName;

    public Product(){}

    @JsonGetter("brandName")
    protected String getBrandName() {
        if (brand != null)
            brandName = brand.getName();
        return brandName;
    }

    @JsonSetter("brandName")
    protected void setBrandName(String brandName) {
        if (brandName != null) {
            brand = new Brand();
            brand.setName(brandName);
        }
        this.brandName = brandName;
    }

//other accessors and mutators
}

Here, the brand instance will be ignored by Jackson during serialization and deserialization , since it is annotated with @JsonIgnore

Jackson will use the method annotated with @JsonGetter for serialization of java object into JSON format.因此, brandName 设置为 brand.getName()

Similarly, Jackson will use the method annotated with @JsonSetter for deserialization of JSON format into java object.在这种情况下,您必须自己实例化 brand 对象并设置它的 name 来自 brandName --- 的属性。

您可以将 @Transient 持久性注释与 brandName 一起使用,如果您希望持久性提供程序忽略它。

原文由 Sunny KC 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题