gpt4 book ai didi

java - 从 json 反序列化到包含枚举的对象的问题

转载 作者:行者123 更新时间:2023-11-30 01:47:54 29 4
gpt4 key购买 nike

使用 jackson2.9.8 进行枚举反序列化时遇到问题。 Gson 也同样可以正常工作。模型是根据 swagger api 定义自动生成的

使用Gson,效果很好。对于 Jackson,它不适用于 011、013 和 019,但适用于其他值

Swagger API 定义片段

服务代码: 类型:字符串 枚举: - “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 生成 pojo。 @JsonAdapter(ServiceCodeEnum.Adapter.class) 行是一个适配器,用于处理 Gson 的枚举转换。

<小时/>

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

据说:对于所有未指定的选项,将使用默认值。

上面列出了下表:

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(默认)- HTTP 客户端:OkHttp 2.4.0。 JSON处理:Gson 2.3.1

您需要指定一个使用 Jackson 的库和您想要的 HTTP 客户端。

关于java - 从 json 反序列化到包含枚举的对象的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57261821/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com