2017-11-11 9 views
1

나는 stackoverflow과 구글 에서이 질문에 대한 검색과 나는 어떤 적절한 답변을 찾을 수 없습니다.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":1, 
    "name":"some engine" 
    "producer":"some engine producer" 
    "horsePower":250 
    "weight":500 
} 

id, name, producer, horsePower, weight 그냥 명확히하는 모든 필드로 구성한다. horsePowerweight 필드는 자동차에서 생성 된 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을 활성화합니다. 이전에 필드가 Engine 인 경우 Engine에있는 원하지 않는 필드가 건너 뛴다는 것을 확인하는 자신의 개인용으로 ExclusionStrategy 레지스터를 건너 뜁니다.

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

고마워, 이것이 내가 찾고 있었던 것이었다. 솔루션의 유일한 문제점은 예외를 문자열로 제공해야하므로 유형 안전하지 않습니다. 그러나 나는 이것이 타입 세이프가 될 수있는 방법을 보면서 투쟁한다. 그리고 나는 이것을위한 완벽한 해결책이 없다고 생각한다. ExclusionStrategy를 만들려고 노력 중이라면 확신 할 수 없습니다. 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 
}