2017-09-25 2 views
0

JSON 문자열을 필드 중 하나에 설정된 값에 따라 다른 Object 유형의 목록으로 Jackson을 사용하여 비 직렬화해야합니다. 다른 목록 유형을 만드는 가장 좋은 방법은 무엇인지, 그리고 어떻게 구현할 수 있는지 알고 싶습니다. 이 같은Jackson은 JSON을 문자열 값에 따라 다른 유형의 목록으로 비 병렬화

내 JSON의 보일 것이다 뭔가 : 구문 분석시

{"test": 
    {"conditions":[....],     
    "consequence": {"actionType":"string", 
        "action": ["value 1","value 2"]}            
    }  
} 

은 그래서 위의 List<String>

{"test": 
    {"conditions":[....],     
    "consequence": {"actionType":"test", 
        "action": ["test","test"]}            
    }  
} 

을 반환하고는 위의 List<Test>

내 뽀조 단지 포함 반환 :

@Data 
public class Consequence { 

    public Consequence(String actionType){ 
     this.actionType = actionType;  
    }; 

    @JsonProperty("ACTIONTYPE") 
    private String actionType; 

    @JsonProperty("ACTION") 
    private List<????> action; 
} 

업데이트 :

는 두 가지 변종이 있습니다
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token 
at [Source: {"TEST":{"CONDITIONS":[{"KEY":"KEY1","VALUES":["FLOAT"],"OPERATOR":""}],"CONSEQUENCE":{"ACTIONTYPE" :{"CONCATENATE": ["VALUE1","VALUE2"]}}}}; line: 1, column: 9] (through reference chain: package.TestCase["TEST"]) 

답변

1

당신이 사용할 수 있습니다 :

나는 다음과 같은 오류가

@Data 
public abstract class BaseConsequence { 

    public BaseConsequence(String actionType){ 
     this.actionType = actionType;  
    }; 

    @JsonProperty("ACTIONTYPE") 
    private String actionType; 

} 

@Data 
@DiscriminatorValue(value = "CONCATENATE") 
public class ConcatenateConsequence extends BaseConsequence { 

    public ConcatenateConsequence(String actionType, List<String> concatenateValues) { 
     super(actionType); 
     this.concatenateValues = concatenateValues; 
    } 
    private List<String> concatenateValues; 
} 

@Data 
@DiscriminatorValue(value = "test") 
public class TestConsequence extends BaseConsequence { 

    public TestConsequence(String actionType, List<Test> tests){ 
     super(actionType); 
     this.tests = tests; 
    } 
    private List<Test> tests; 
} 

@Data 
public class Test { 

    public Test(){}; 

    public Test(List<Condition> conditions, BaseConsequence baseConsequence){ 
     this.conditions = conditions; 
     this.baseConsequence = baseConsequence;  
    } 

    @JsonProperty("CONDITIONS") 
    private List<Condition> conditions; 

    @JsonProperty("CONSEQUENCE") 
    private BaseConsequence baseConsequence; 

    @Override 
    public boolean equals(Object o) { 

     if (o == this) return true; 

     if (!(o instanceof Test)) { 
      return false; 
     }   
     Test test = (Test) o; 
     return Objects.equals(conditions, test.conditions) && Objects.equals(baseConsequence, test.baseConsequence); 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hash(conditions, baseConsequence); 
    } 
} 

:

나는 다음과 같은 계층 구조를 사용하여 내 POJO의 업데이트 후

  1. 사용자 정의 직 병렬 변환기를 만듭니다. 전체 설명 및 예제는 여기를 참조하십시오. http://www.baeldung.com/jackson-deserialization
  2. 가장 좋은 방법은 하나의 기본 클래스와 두 개의 자식을 사용하는 것입니다. 각 어린이는 @DiscriminatorValue으로 표시해야합니다. http://www.baeldung.com/jackson-inheritance
+0

당신이, 내가 옵션을 체크 아웃거야, 그리고 내가 한 – Orby

+0

올렉를 구현할 수 있다면 사용자 정의 디시리얼라이저 내가 전화 내 속성을 확인해야합니까 "actionType을 구현하는 경우, 참조 올렉 감사에 대한 자세한 설명과 예 ​​여기를 참조하십시오 "덮어 쓴 deserialize 메서드에서 적절한 List Type을 반환하십시오. – Orby

+0

예. 디시리얼라이저에서는 json 파트에 액세스 할 수 있습니다. 먼저 * 키 필드 *를 읽은 다음 특정 데이터로 하나의 오브젝트를 구성하거나 dirrefernt 오브젝트를 작성해야합니다. 이것은 매우 강력한 기능이지만'@ DiscriminatorValue'를보기를 강력히 권합니다. –