2016-07-28 5 views
1

Я пытаюсь десериализовать результат, возвращенный из вызова API. Однако результат может содержать либо логическое, либо массив.Jackson Boolean и Array Связывание данных

Если результат логического, JSON, полученные в ответ выглядит как

{ 
    "succeeded": true, 
    "version": 1.0 
} 

Если результат массив JSON, полученные в JSON ответ выглядит

{ 
    "succeeded": { 
    "current_page": 1, 
    "per_page": 100, 
    "results": [ 
    { 
     "get_info": { 
     "fieldA": "4198126", 
     "fieldB": "2016-05-25T22:43:52Z", 
     "fieldC": "iws-user-cfg-proxy-beta", 
     "updated_at": "2016-05-25T22:43:52Z" 
     } 
    }, 
    { 
     "get_info": { 
     "fieldA": "4551542", 
     "fieldB": "2016-07-27T22:26:27Z", 
     "fieldC": "silkRoot", 
     "updated_at": "2016-07-27T22:26:27Z" 
     } 
    } 
    ] 
}, 
"version": 1.0 
} 

Я хотел бы прочитать значение, связанное с успешное поле. Есть ли способ, которым я могу справиться с этим в классе сопоставления. Мой текущий класс отображение, как показано ниже:

public class ServResp { 

public final static String TYPE1_EXCEPTION = "Type1Exception"; 
public final static String TYPE2_EXCEPTION = "Type2Exception"; 

public final int httpStatusCode; 
public final boolan succeeded; 
public final String version; 
public final String exception; 
public final String exceptionMessage; 

private ServResp(Builder builder) { 
    this.httpStatusCode = builder.httpStatusCode; 
    this.succeeded = builder.succeeded; 
    this.version = builder.version; 
    this.exception = builder.exception; 
    this.exceptionMessage = builder.exceptionMessage; 
} 

public Builder modify() { 
    return new Builder(this); 
} 

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ((exception == null) ? 0 : exception.hashCode()); 
    result = prime * result + ((exceptionMessage == null) ? 0 : exceptionMessage.hashCode()); 
    result = prime * result + httpStatusCode; 
    result = prime * result + (succeeded ? 17 : 19); 
    result = prime * result + ((version == null) ? 0 : version.hashCode()); 
    return result; 
} 

@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    ServResp other = (ServResp) obj; 
    if (exception == null) { 
     if (other.exception != null) 
      return false; 
    } else if (!exception.equals(other.exception)) 
     return false; 
    if (exceptionMessage == null) { 
     if (other.exceptionMessage != null) 
      return false; 
    } else if (!exceptionMessage.equals(other.exceptionMessage)) 
     return false; 
    if (httpStatusCode != other.httpStatusCode) 
     return false; 
    if (succeeded != other.succeeded) 
     return false; 
    if (version == null) { 
     if (other.version != null) 
      return false; 
    } else if (!version.equals(other.version)) 
     return false; 

    return true; 
} 

public static class Builder { 

    private int httpStatusCode; 
    private boolean succeeded; 
    private String version; 
    private String exception; 
    private String exceptionMessage; 

    public Builder() { 
    } 

    public Builder(ServResp other) { 
     this.httpStatusCode = other.httpStatusCode; 
     this.version = other.version; 
     this.exception = other.exception; 
     this.exceptionMessage = other.exceptionMessage; 
    } 

    public Builder setHttpStatusCode(int httpStatusCode) { 
     this.httpStatusCode = httpStatusCode; 
     return this; 
    } 

    public Builder setSucceeded(boolean succeeded) { 
     this.succeeded = succeeded; 
     return this; 
    } 

    public Builder setVersion(String version) { 
     this.version = version; 
     return this; 
    } 

    public Builder setException(String exception) { 
     this.exception = exception; 
     return this; 
    } 

    public Builder setExceptionMessage(String exceptionMessage) { 
     this.exceptionMessage = exceptionMessage; 
     return this; 
    } 

    public ServResp build() { 
     return new ServResp(this); 
    } 
}} 

Если я выполнить программу так, как это, я получаю ниже ошибки:

Caused by: org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.lang.boolean out of START_OBJECT token 

Есть ли способ обойти это?

Благодаря

ответ

1

Вы могли бы попробовать изменить тип Builder.succeeded к Object, а затем добавить некоторый код, чтобы прочитать его позже. Это звучит как источник будущих ошибок, но если вы не контролируете API, это может быть вашим лучшим выстрелом.

public class Foo { 
     private Object overRiddenJsonType; 

     public Object getOverRiddenJsonType() { 
      return overRiddenJsonType; 
     } 

     public void setOverRiddenJsonType(Object overRiddenJsonType) { 
      this.overRiddenJsonType = overRiddenJsonType; 
     } 
    } 

    public class FooConsumer { 
     public void consumeFoo(Foo foo) { 
      Boolean b = false; 
      Bar bar = null; 
      if (foo.getOverRiddenJsonType() instanceof Boolean) { 
       b = (Boolean)foo.getOverRiddenJsonType(); 
       // worry about NPE from unboxing later... 
      } else if (foo.getOverRiddenJsonType() instanceof Bar) { 
       bar = (Bar)foo.getOverRiddenJsonType(); 
      } 
      // ... 
     } 

}

Если, с другой стороны, вы контролировать API, то лучшим решением будет реструктурировать свой JSON таким образом, что success всегда boolean, а остальные данные либо поле верхнего уровня или член results:

{ 
     "succeeded": true, 
     "version": 1.0, 
     "current_page": 1, 
     "per_page": 100, 
     "results": [ 
     { 
      "get_info": { 
      "fieldA": "4198126", 
      ... 
      } 
     ] 
    } 
+0

У меня есть контроль над API ... Я думаю, что ваш второй подход намного лучше ... Попробуем это ... Спасибо – learningMyWayThru

1

Я хотел бы предложить, чтобы сгенерировать простой POJO для JSON ниже, с помощью этого инструмента jsonschematopojo. При генерации pojo вы можете выбрать тип источника как стиль JSON и Annotation: none.

{ 
    "succeeded": { 
    "current_page": 1, 
    "per_page": 100, 
    "results": [ 
    { 
     "get_info": { 
     "fieldA": "4198126", 
     "fieldB": "2016-05-25T22:43:52Z", 
     "fieldC": "iws-user-cfg-proxy-beta", 
     "updated_at": "2016-05-25T22:43:52Z" 
     } 
    }, 
    { 
     "get_info": { 
     "fieldA": "4551542", 
     "fieldB": "2016-07-27T22:26:27Z", 
     "fieldC": "silkRoot", 
     "updated_at": "2016-07-27T22:26:27Z" 
     } 
    } 
    ] 
} 
} 

После того, как вы добавили сгенерированный боб в ваш проект, вы можете добавить этот перегруженный метод в классе картографа

private Succeeded succeeded; 

/** 
* 
* @return 
*  The succeeded 
*/ 
public Succeeded getSucceeded() { 
    return succeeded; 
} 

/** 
* 
* @param succeeded 
*  The succeeded 
*/ 
public void setSucceeded(Succeeded succeeded) { 
    this.succeeded = succeeded; 
} 

Пожалуйста, проверьте, если этот подход работает.

+0

Спасибо за ваше предложение. Этот инструмент полезен для преобразования json в объект POJO, который может использоваться как базовый – learningMyWayThru