2017-07-13 4 views
1

現在、ジャクソンを使用してJSONをJavaオブジェクトに逆シリアル化しています。すべてがうまく動作しますが、私はまた、いくつかのフィールドなどがあります。ジャクソン注釈を使用してJavaクラスに大量のプロパティを持つjsonを非直列化する

@Test 
public void testBalanceJSON() throws IOException { 
    // Read in the JSON from the example resources 
    InputStream is = BalanceTest.class.getResourceAsStream("/example-balance-data.json"); 
    //Use Jackson to parse it 
    ObjectMapper mapper = new ObjectMapper(); 
    Balance balance = mapper.readValue(is, Balance.class); 
} 

... ... 

@JsonIgnoreProperties(ignoreUnknown = true) 
public class Balance { 
    private final BigDecimal uid; 
    private final BigDecimal asset; 
    private final BigDecimal currency1Balance; 
    private final BigDecimal currency2Balance; 
    // ... ... 
    private final BigDecimal currencyNBalance; 

    @JsonCreator 
    public Balance(@JsonProperty("uid") BigDecimal uid, @JsonProperty("asset") BigDecimal asset, 
       @JsonProperty("currency1_balance") BigDecimal currency1Balance, 
       @JsonProperty("currency2_balance") BigDecimal currency2Balance, 
       // ... ... 
       @JsonProperty("currencyN_balance") BigDecimal currencyNBalance) { 
        this.uid = uid; 
        this.asset = asset; 
        this.currency1Balance = currency1Balance; 
        this.currency2Balance = currency2Balance; 
        // ... ... 
        this.currencyNBalance = currencyNBalance; 
       } 
} 

上記の場合:

{ 
    "uid": 7, 
    "asset": 123, 
    "currency1_balance": 0, 
    "currency2_balance": 0, 

    ... ... 

    "currencyN_balance": 0, 
} 

は、我々は以下のJavaクラスを経由して、それをデシリアライズすることができます:JSONファイルのこの種の

私は、 "currencyN_balance"と "currencyNBalance"の間のマッピングに対処するために、たくさんのコードを書く必要があります。通貨が追加/削除されると、それに応じてコードを修正する必要があります。これはかなり柔軟性がありません。 次に、デシリアライズプロセスをカスタマイズするための次の方法が見つかりました。

@JsonCreator 
    public static Balance Create(Map<String, Object> jsonMap) { 
    //Resovle the map 
    BigDecimal uid = new BigDecimal(jsonMap.get("uid").toString()); 
    BigDecimal asset = new BigDecimal(jsonMap.get("asset").toString()); 
    for (Map.Entry<String, Object> entry : jsonMap.entrySet()){ 
     if (entry.getKey().startsWith("currency")) { 
      //Do something... 
     } 
    } 
    //Then construct the Balance instance and return 
    } 

上記の方法を使用すると、退屈でエラーが発生しやすいマッピングを取り除くことができます。しかし、私はいくつかのパラメータの非直列化(例えば、UID、資産)に対処するためにアノテーションを活用することはできません。

上記の両方の手法の強みを組み合わせる方法はありますか? (通貨マッピングをカスタマイズできるうちに、uid、assetなどのパラメータを使用する注釈を使用)

ありがとうございました。

+0

なぜBigDecimal [] currencyBalances; '? –

答えて

1

これはJSONの忌み嫌いです。そのcurrency_ [1..n] _balanceは配列でなければなりません...それは配列だが、ぎこちない方法でコード化されているからです。

とにかく、あなたのせいではありません(私は願っています)。このため、Jackson @ JsonAnyGetterアノテーションと@JsonAnySetterアノテーションを使用できます(このクラスをシリアライズおよびデシリアライズしたい場合は、それ以外の場合は1つだけ使用できます)。例えば

@JsonAnySetter 
public void set(String name, String value) { 
    //do funky transformation/assigment 
} 

ジャクソンはそれがマップすることはできません任意のプロパティでそのメソッドを呼び出します。したがって、興味のないプロパティを無視するロジックを追加する必要があります。

関連する問題