2016-07-28 13 views
1

Ich versuche deserialize das Ergebnis von API-Aufruf zurückgegeben. Das Ergebnis kann jedoch entweder einen booleschen Wert oder ein Array enthalten.Jackson Boolean und Array Datenbindung

Wenn das Ergebnis boolean ist, json als Antwort erhielt sieht aus wie

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

Wenn das Ergebnis Array, json in Reaktion json empfangen sieht aus wie

{ 
    "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 
} 

Ich möchte den Wert lesen, die mit gelungenes Feld. Gibt es eine Möglichkeit, das kann ich in der Mapping-Klasse umgehen. Meine aktuelle Mapping-Klasse ist wie folgt:

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); 
    } 
}} 

Wenn ich das Programm den Weg auszuführen ist, erhalte ich unten Fehler:

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

Gibt es eine Möglichkeit, dies zu umgehen?

Dank

Antwort

1

Sie könnten versuchen, die Art des Builder.succeeded-Object zu ändern, und dann einen Code hinzufügen, um es später zu lesen. Das hört sich nach einer Quelle zukünftiger Fehler an, aber wenn Sie die API nicht kontrollieren, ist es vielleicht Ihr bester Schnappschuss.

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(); 
      } 
      // ... 
     } 

}

Wenn auf der anderen Seite, können Sie die API steuern tun, dann eine bessere Lösung wäre, um Ihre JSON zu restrukturieren, so dass success ist immer boolean, und den Rest der Daten entweder ist ein Top-Level-Bereich oder ein Mitglied der results:

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

Ich habe die Kontrolle über die API ... Ich denke, Ihr zweiter Ansatz ist viel besser ... Wird versuchen, dass ... Danke – learningMyWayThru

1

ich würde vorschlagen Ebene pojo für json unten unter Verwendung dieses Werkzeugs jsonschematopojo zu erzeugen. Beim Erstellen von Pojo können Sie Quellentyp als JSON und Anmerkungsstil auswählen: keine.

{ 
    "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" 
     } 
    } 
    ] 
} 
} 

Sobald Sie die generierte Bean in Ihrem Projekt hinzugefügt haben, können Sie diese überladene Methode in Ihrem Zuordnerklasse

private Succeeded succeeded; 

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

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

Bitte fügen Sie prüfen, ob dieser Ansatz funktioniert.

+0

Vielen Dank für Ihren Vorschlag. Das Werkzeug ist nützlich, um ein JSON- zu POJO-Objekt zu konvertieren, das als Basis verwendet werden kann – learningMyWayThru