簡體   English   中英

如何使用 Jackson 在 JSON 中解開特定字段?

[英]How can I unwrap a specific field in a JSON using Jackson?

我有一個 JSON 有效負載,如下所示:

{
    "id": 32,
    "name": "[Sample] Tomorrow is today, Red printed scarf",
    "primary_image": {
      "id": 247,
      "zoom_url": "www.site.com/in_123__14581.1393831046.1280.1280.jpg",
      "thumbnail_url": "www.site.com/in_123__14581.1393831046.220.290.jpg",
      "standard_url": "www.site.com/in_123__14581.1393831046.386.513.jpg",
      "tiny_url": "www.site.com/in_123__14581.1393831046.44.58.jpg"
    }
  }

我可以打開特定字段並丟棄所有其他字段嗎? 換句話說,我可以將它直接綁定到這樣的 POJO 嗎:

public class Product {

    private Integer id;
    private String name;
    private String standardUrl;
}

有很多方法。 您是否需要反序列化、序列化或兩者兼而有之?

反序列化的一種方法是使用將圖像作為樹節點的創建者方法:

public static class Product {
    private Integer id;
    private String name;
    private String standardUrl;

    public Product(@JsonProperty("id") Integer id,
                   @JsonProperty("name") String name,
                   @JsonProperty("primary_image") JsonNode primaryImage) {
        this.id = id;
        this.name = name;
        this.standardUrl = primaryImage.path("standard_url").asText();
    }
}

創建者不必是構造函數,您可以有一個僅用於 Jackson 反序列化的靜態方法。

不過,您必須定義一個自定義序列化程序來重新序列化它(例如,一個 StdDelegatingSerializer 和一個轉換器將字符串包裝為 ObjectNode)

有多種方法可以給這只貓剝皮,我希望你可以使用 Jackson 2,因為它提供了反序列化 Json 數據的好方法,我最喜歡的反序列化功能之一是我將在這里展示的功能(使用Builder Pattern ),因為允許您在構造實例時驗證實例(或使它們不可變!)。 對你來說,這看起來像這樣:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import java.util.Map;

@JsonDeserialize(builder = Product.Builder.class)
public class Product {

private Integer id;

private String name;

private String standardUrl;

private Product(Builder builder) {
    //Here you can make validations for your new instance.

    this.id = builder.id;
    this.name = builder.name;

    //Here you have access to the primaryImage map in case you want to add new properties later.
    this.standardUrl = builder.primaryImage.get("standard_url");
}

@Override
public String toString() {
    return String.format("id [%d], name [%s], standardUrl [%s].", id, name, standardUrl);
}

@JsonIgnoreProperties(ignoreUnknown = true)
public static class Builder {

    private Integer id;

    private String name;

    private Map<String, String> primaryImage;

    public Builder withId(Integer id) {
        this.id = id;
        return this;
    }

    public Builder withName(String name) {
        this.name = name;
        return this;
    }

    @JsonProperty("primary_image")
    public Builder withPrimaryImage(Map<String, String> primaryImage) {
        this.primaryImage = primaryImage;
        return this;
    }

    public Product build() {
        return new Product(this);
    }
}
}

為了測試它,我創建了這個類:

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class Test {
public static void main(String[] args) {


    String serialized = "{" +
                        "    \"id\": 32," +
                        "    \"name\": \"[Sample] Tomorrow is today, Red printed scarf\"," +
                        "    \"primary_image\": {" +
                        "      \"id\": 247," +
                        "      \"zoom_url\": \"www.site.com/in_123__14581.1393831046.1280.1280.jpg\"," +
                        "      \"thumbnail_url\": \"www.site.com/in_123__14581.1393831046.220.290.jpg\"," +
                        "      \"standard_url\": \"www.site.com/in_123__14581.1393831046.386.513.jpg\"," +
                        "      \"tiny_url\": \"www.site.com/in_123__14581.1393831046.44.58.jpg\"" +
                        "    }" +
                        "  }";


    ObjectMapper objectMapper = new ObjectMapper();

    try {

        Product deserialized = objectMapper.readValue(serialized, Product.class);

        System.out.print(deserialized.toString());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

輸出是(使用Product的覆蓋toString()方法:

id [32], name [[Sample] Tomorrow is today, Red printed scarf], standardUrl [www.site.com/in_123__14581.1393831046.386.513.jpg].

有兩種方法可以獲得您需要的響應。 對於這兩種方法,我們將使用 JsonView。

創建兩種類型的 JsonView:

public interface JViews {
    public static class Public { }
    public static class Product extends Public { }
}

第一種方法

@JsonView(JViews.Public.class)
public class Product {
    private Integer id;
    private String name;
    @JsonIgnore
    private Image primaryImage;
    @JsonView(JViews.Product.class)
    public String getStandardUrl{
       return this.primaryImage.getStandardUrl();
    }
}

第二種方式

一起使用 Jackson 的 @JsonView 和 @JsonUnwrapped。

@JsonView(JViews.Public.class)
public class Product {
    private Integer id;
    private String name;

    @JsonUnwrapped
    private Image primaryImage;
}
public class Image {
   private String zoomUrl;
   @JsonView(JViews.Product.class)
   private String standardUrl;
}

@JsonUnwrapped 注釋將您的嵌套對象展平為 Product 對象。 並且 JsonView 用於過濾可訪問的字段。 在這種情況下,Product 視圖只能訪問 standardUrl 字段,結果應該是:

{
    "id": 32,
    "name": "[Sample] Tomorrow is today, Red printed scarf",
    "standard_url": "url"
}

如果在不使用視圖的情況下展平嵌套對象,結果將如下所示:

{
    "id": 32,
    "name": "[Sample] Tomorrow is today, Red printed scarf",
    "id":1,
    "standard_url": "url", 
    "zoom_url":"",
    ...
}

Jackson 提供了 @JsonUnwrapped 注釋。

見以下鏈接:

http://jackson.codehaus.org/1.9.9/javadoc/org/codehaus/jackson/annotate/JsonUnwrapped.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM