簡體   English   中英

從json反序列化到包含枚舉的對象的問題

[英]Issue with de-serialization from json to object containing enums

使用jackson2.9.8進行枚舉反序列化時遇到問題。 Gson也可以正常工作。 模型是根據swagger API定義自動生成的

使用Gson,效果很好。 對於傑克遜,它不適用於011、013和019,但適用於其他值

Swagger API定義的摘要

serviceCode:類型:字符串枚舉:-“ 001”-“ 002”-“ 003”-“ 004”-“ 005”-“ 007”-“ 008”-“ 009”-“ 011”-“ 013”-“ 019 “

自動生成的代碼(刪除了getter / setter以提高可讀性)

public class ProcessErrorTest1 {
    static String errorJson =
            "    {\n" +
            "      \"timestamp\": \"2019-07-29 11:55:48\",\n" +
            "      \"serviceCode\": \"019\",\n" +
            "      \"message\": \"service failed. \",\n" +
            "      \"rootException\": {\n" +
            "        \"source\": \"test\",\n" +
            "        \"reasonCode\": \"2131\",\n" +
            "        \"reasonText\": \"test\"\n" +
            "      }\n" +
            "}";

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        AppErrorResponse error = mapper.readValue(errorJson, AppErrorResponse.class);
       // Gson gson = new Gson();
        //AppErrorResponse error = gson.fromJson(errorJson, AppErrorResponse.class);
        System.out.println("error::" + error);
    }
}

public class AppErrorResponse {

  @SerializedName("message")
  private String message = null;

  @SerializedName("rootException")
  private ErrorResponse rootException = null;
  /**
   * Gets or Sets serviceCode
   */
  @JsonAdapter(ServiceCodeEnum.Adapter.class)
  public enum ServiceCodeEnum {
    _001("001"),
    _002("002"),
    _003("003"),
     _004("004"),
    _005("005"),
    _007("007"),
    _008("008"),
    _009("009"),
    _011("011"),
    _013("013"),
   // @JsonProperty("019") if add this , it works fine. But can't modify the auto generated code as it is available as jar
    _019("019");
  }
  @SerializedName("serviceCode")
  private ServiceCodeEnum serviceCode = null;

  @SerializedName("timestamp")
  private String timestamp = null;

}

public class ErrorResponse {

  @SerializedName("reasonCode")
  private String reasonCode = null;

  @SerializedName("reasonText")
  private String reasonText = null;

  @SerializedName("source")
  private String source = null;
}

jersey1:jackson生成代碼

import java.util.Objects;
import com.bt.consumer.appointment.dto.MAC2ErrorResponse;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
public class AppErrorResponse {
  @JsonProperty("message")
  private String message = null;

  @JsonProperty("rootException")
  private ErrorResponse rootException = null;

  public enum ServiceCodeEnum {
    _001("001"),
    _002("002"),
    _003("003"),
    _004("004"),
    _005("005"),
    _007("007"),
    _008("008"),
    _009("009"),
    _011("011"),
    _013("013"),
    _019("019");

    private String value;

    ServiceCodeEnum(String value) {
      this.value = value;
    }
    @JsonValue
    public String getValue() {
      return value;
    }

    @Override
    public String toString() {
      return String.valueOf(value);
    }
    @JsonCreator
    public static ServiceCodeEnum fromValue(String text) {
      for (ServiceCodeEnum b : ServiceCodeEnum.values()) {
        if (String.valueOf(b.value).equals(text)) {
          return b;
        }
      }
      return null;
    }

  }
  @JsonProperty("serviceCode")
  private ServiceCodeEnum serviceCode = null;

  @JsonProperty("timestamp")
  private String timestamp = null;
}

import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
public class ErrorResponse {
  @JsonProperty("reasonCode")
  private String reasonCode = null;

  @JsonProperty("reasonText")
  private String reasonText = null;

  @JsonProperty("source")
  private String source = null;
}

使用jackson錯誤消息,它除_011,_013和_019以外的所有內容都正常工作:-com.fasterxml.jackson.databind.exc.InvalidFormatException:無法從字符串“ 011”反序列化ServiceCodeEnum類型的值:值不是聲明的Enum實例名稱之一:[_ 011,_001,_002,_003,_004,_005,_007,_008,_009,_013,_019]

您的注釋針對Gson而不是Jackson,您應該為Jackson而不是Gson生成pojos。 @JsonAdapter(ServiceCodeEnum.Adapter.class)是一個適配器,用於處理Gson的該枚舉的轉換。


查看swagger codegen文檔,您會找到有關生成https://github.com/swagger-api/swagger-codegen#customizing-the-generator的部分

據說: For all the unspecified options default values will be used.

上面列出了下表:

CONFIG OPTIONS
    modelPackage
        package for generated models

    apiPackage
        package for generated api classes
...... (results omitted)
    library
        library template (sub-template) to use:
        jersey1 - HTTP client: Jersey client 1.18. JSON processing: Jackson 2.4.2
        jersey2 - HTTP client: Jersey client 2.6
        feign - HTTP client: Netflix Feign 8.1.1.  JSON processing: Jackson 2.6.3
        okhttp-gson (default) - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1
        retrofit - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1 (Retrofit 1.9.0)
        retrofit2 - HTTP client: OkHttp 2.5.0. JSON processing: Gson 2.4 (Retrofit 2.0.0-beta2)
        google-api-client - HTTP client: google-api-client 1.23.0. JSON processing: Jackson 2.8.9
        rest-assured - HTTP client: rest-assured : 3.1.0. JSON processing: Gson 2.6.1. Only for Java8

這行可能是正在使用的內容:

okhttp-gson (default) - HTTP client: OkHttp 2.4.0. JSON processing: Gson 2.3.1

您需要指定一個庫,該庫使用Jackson和所需的HTTP客戶端。

暫無
暫無

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

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