2017-11-11 6 views
1

私はこの質問をstackoverflowとgoogleで検索しましたが、適切な答えが見つかりませんでした。JSONシリアライゼーションで、Class1がClass2のフィールドの場合、Class1フィールドの一部を無視しますか?

オブジェクト内のオブジェクトのフィールドを無視するにはどうすればよいですか?

class Car { 
    Integer id; 
    Integer numberOfWheels; 
    Engine engine; 
} 

class Engine { 
    Integer id; 
    String name; 
    String producer; 
    Integer horsePower; 
    Integer weight; 
} 

カーJSONが構成される必要があります:(Class1 = EngineClass2 = Carためのフィールドのタイトルで、編集者注)

は、私は一例と理解することがはるかに容易になると思いますCarオブジェクト内のEngineオブジェクトはid, name, producerに制限する必要があります。

{ 
    "id":1, 
    "numberOfWheels":4, 
    "engine": { 
    "id":1, 
    "name":"some engine" 
    "producer":"some engine producer" 
    } 
} 

エンジンJSONは、しかし、ちょうど明確にするid, name, producer, horsePower, weight

{ 
    "id":1, 
    "name":"some engine" 
    "producer":"some engine producer" 
    "horsePower":250 
    "weight":500 
} 

すべてのフィールドで構成する必要があります。 horsePowerweightフィールドは、Carから生成されたJSONでは無視する必要があります。

+0

あなたはgsonを使用するか、春のJSONのlibsに依存しないといけませんの? Springとそのjsonハンドリングに慣れていない、Springが使用しているjsonの実装は? – pirho

+0

私はgsonを使うことができます、私は春だけに固執する必要はありません。私はベストプラクティスとタイプセーフなソリューションを探しています。 – kkflf

答えて

1

gsonJsonSerializerExclusionStrategyの表情を持っています。それを行うための最も簡潔な方法ではないかもしれません - 特にあなた自身の解決策に比べて - しかし一般的には良い選択です。

上記のみCarと台無しにしない、他のシリアライズをするを処理するために、gson独自のを持っていJsonSerializer

public class CarSerializer implements JsonSerializer<Car> { 
    private final Gson gson = new GsonBuilder() 
      .addSerializationExclusionStrategy(new FieldExclusionStrategy()).create(); 

    @Override 
    public JsonElement serialize(Car arg0, Type arg1, JsonSerializationContext arg2) { 
     return new JsonParser().parse(gson.toJson(arg0)); 
    } 
} 

のようないくつかの特別な治療を作成してもらうために Carを有効にするには。前述のレジスタ ExclusionStrategyは、 Carのフィールドが Engineである場合、 Engineの不要なフィールドはスキップされることをチェックします。

public class FieldExclusionStrategy implements ExclusionStrategy { 
    private Set<String> ignored = 
      new HashSet<String>(Arrays.asList(new String[]{"horsePower","weight"})); 
    @Override 
    public boolean shouldSkipField(FieldAttributes arg0) { 
     if(arg0.getDeclaringClass().isAssignableFrom(Engine.class)) 
      if(ignored.contains(arg0.getName())) return true; 
     return false; 
    }  
    @Override 
    public boolean shouldSkipClass(Class<?> arg0) { return false; } 
} 

そして、それはCar.classのために、そのタイプのアダプタとしてJsonSerializerを登録gsonで使用することができます:

Gson gson = new GsonBuilder().setPrettyPrinting() 
     .registerTypeAdapter(Car.class, new CarSerializer()).create(); 
+0

ありがとう、これは私が探していたものでした。このソリューションの唯一の問題は、除外を文字列として提供する必要があるため、型保証されていないことです。私はしかし、これはtypesafeを行うことができる方法を参照してください苦労し、私はそこに完璧な解決策ではないと思う。 ExclusionStrategyを作成しようと努力しているのかどうかは確信が持てません。これは、同じオブジェクトに対して異なるラッパーオブジェクトに対して多くの除外が行われる可能性があるためです。私のソリューションにExclusionStrategyを使用することをお勧めしますか?これは特定の問題ではなく、私はベストプラクティスの解決策を見つけたいだけです – kkflf

+1

はい、すべての方法で型エラーではなく、エラーチェックでも完璧ではありません。しかし、私はあなたがこの時点からその部分を扱うことができると確信しています。私はそれがまだ可能であると確信しています。あなたのソリューションには、一生に一度良いですが、私はエンティティ/モデルに干渉しないものを好む傾向があります。言い換えれば、私のソリューションはあなたのエンティティ/モデルに対するビューです。あなたのクラスをもう修正するか、あるいは恐ろしい副作用を引き起こす可能性があります。 – pirho

+0

クロスカッティングに関する非常に良い点があります。あなたの助けに感謝します。それは常に第二の意見で素晴らしいです。 – kkflf

0

私は気楽になり、より良い方法を見つけるまで一時的な解決策を作成することに決めました。このソリューションはベストプラクティスである場合とそうでない場合がありますが、私はこれ以上の解決策はありません。

誰かがこの質問を見つけて解決策について不思議に思うなら、一時的な解決策を投稿することに決めました。

私はまだタイプセーフなベストプラクティスのソリューションを探しています。だれでも回答があれば投稿してください。ソリューションを投稿するタイミングに関係なく、私はあなたの答えを受け入れます。

class Car { 
    Integer id; 
    Integer numberOfWheels; 
    @JsonIgnore 
    Engine engine; 

    @JsonProperty("engine") 
    public Map<String, Object> getEngineFormatted(){ 
     return engine == null ? null : engine.getFormatted(); 
    } 
} 

class Engine { 
    Integer id; 
    String name; 
    String producer; 
    Integer horsePower; 
    Integer weight; 

    public Map<String, Object> getFormatted(){ 
     Map<String, Object> map = new HashMap<>(); 

     map.put("id", id); 
     map.put("name", name); 
     map.put("producer", producer); 

     return map; 
    } 
} 

カーJSON:

{ 
    "id":1, 
    "numberOfWheels":4, 
    "engine": { 
    "id":1, 
    "name":"some engine" 
    "producer":"some engine producer" 
    } 
} 

エンジンJSON

{ 
    "id":1, 
    "name":"some engine" 
    "producer":"some engine producer" 
    "horsePower":250 
    "weight":500 
} 
関連する問題