2

このオブジェクトがあると仮定します:

class Person {
   String name;
   Household getHousehold();
}

class Household {
   Set<Address> getAddresses();
   String householdId;
}

通常、次のようにシリアル化されます

{
  "name": "XXX",
  "household": {
    "addresses": [...]
  }
}

これを取得するためにアノテーション/ミックスインを使用してJacksonを構成する方法はありますか(つまり、DTOを使用せずに)?

{
  "name": "XXX",
  "addresses": [...],
  "household": {
    "householdId": 123
  }
}
4

1 に答える 1

3

mixin と注釈の両方を使用して、特定のプロパティのラップ解除を構成できます。

1.ミックスイン

次の mixin を定義するとします。

public abstract class UnwrappedAddresses {

        @JsonUnwrapped
        public abstract Household getHouseHold();

    }

次に、カスタム モジュールを objectMapper に追加して、次のように mixin を Person クラスに適用します。

ObjectMapper objectMapper = new ObjectMapper();
objectMapper .registerModule(new SimpleModule() {
            @Override
            public void setupModule(SetupContext context) {
                context.setMixInAnnotations(Person.class, UnwrappedAddresses.class);
            }

        });

このアプローチでは、世帯のシリアル化を単一のアイテムとして変更することはありませんが、世帯のアイテムが Person オブジェクトにカプセル化されている場合はラップを解除するだけです。

2. 注釈

@JsonUnwrappedを getHouseHold() メソッドに追加するだけです。

編集:投稿の変更後。

あなたが望むのは、基本的にjsonの出力を変更することです。これは、@JsonAnyGetterアノテーションを使用して行うことができます(新しいプロパティをpojoに動的に追加できます)。

期待される結果は、世帯プロパティを無視し、@JsonAnyGetter を使用してアンラップすることで達成できます。

@JsonIgnoreProperties("houseHold")
public static class Person {
   String name;

   Household houseHold;

    @JsonAnyGetter
    public Map<String,Object> properties(){
      Map<String,Object> additionalProps=new HashMap<>();
      additionalProps.put("addresses", new ArrayList<>(houseHold.getAddresses()));
      Map<String,Object> houseHolProps=new HashMap<>();
      houseHolProps.put("houseHoldId", houseHold.id);
      additionalProps.put("houseHold", houseHolProps);
      return additionalProps;
     }
        ..getters&setters omitted
}

シリアル化後にどちらが返されるか

{"name":"name",
 "houseHold":{"houseHoldId":0},
 "addresses":[
         {"houseNo":2,"street":"abc"},
         {"houseNo":1,"street":"str"}
  ]
 }
于 2016-12-20T17:39:16.543 に答える