簡體   English   中英

使用 Jackson 進行布爾和數組數據綁定

[英]Boolean and array data binding using Jackson

我正在嘗試反序列化從 API 調用返回的結果。 但是,結果可以包含布爾值或數組。

如果結果是布爾值,則響應中收到的 JSON 內容如下所示:

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

如果結果是一個數組,則響應中收到的 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);
    }
}}

如果我按原樣執行程序,則會出現以下錯誤:

引起:org.codehaus.jackson.map.JsonMappingException:無法從 START_OBJECT 令牌中反序列化 java.lang.boolean 的實例

有沒有辦法解決這個問題?

您可以嘗試將Builder.succeeded的類型Builder.succeededObject ,然后添加一些代碼以供稍后閱讀。 這聽起來像是未來錯誤的來源,但如果您不控制 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 an 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",
        ...
      }
   ]
}

我建議使用工具JSONschema2POJO為下面的 JSON 內容生成一個普通的POJO

在生成 POJO 時,您可以選擇Source type作為JSONAnnotation style作為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"
                }
            }
        ]
    }
}

將生成的 bean 添加到項目中后,您可以在映射器類中添加此重載方法:

private Succeeded succeeded;

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM