JsonMappingException:不是地图,不是数组或不是枚举
Posted
技术标签:
【中文标题】JsonMappingException:不是地图,不是数组或不是枚举【英文标题】:JsonMappingException: Not a map, not an array or not an enum 【发布时间】:2020-06-27 10:44:20 【问题描述】:我正在开发一个 rest api 应用程序,但我的代码有一些问题。我想返回一个扩展 avro 架构并将 HATEOAS 链接添加到响应的对象。我做了一些调查,结果发现我需要为对象自定义序列化程序。
有问题的部分代码是:
@JsonValue
public String serialize() throws JsonProcessingException
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(this);
返回
无法编写 JSON:不是枚举。
当前对象是 avro 模式的扩展。我也试过了:
@JsonValue
public String serialize() throws JsonProcessingException
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(getUserData());
返回:
无法写入 JSON:不是数组
其中用户数据是一个实际的 avro 对象。我不明白这些错误是什么意思。有人可以解释吗?另外,有没有更好的方法来返回一个结合其他参数的 avro 对象?
谢谢
编辑:
这里是完整的例子:
public class PaginatedUserData extends UserDataAvro
@JsonValue
public String serialize() throws JsonProcessingException
ObjectMapper mapper = new ObjectMapper();
HashMap<String, String> map = new HashMap<>();
map.put("test", "5");
return mapper.writeValueAsString(map);
返回:
无法写入 JSON:不是数组
【问题讨论】:
【参考方案1】:从@AvroGenerated
类(带有 Micronaut 框架的 Kotlin)中序列化 Kafka 消息时,我遇到了同样的问题。对我有用的是确保使用 Avro 序列化程序,如下所示:
override fun getProperties() = mutableMapOf(
"kafka.bootstrap.servers" to kafka.bootstrapServers,
"kafka.producers.default.value.serializer" to KafkaAvroSerializer::class.java.name,
"kafka.producers.default.key.serializer" to StringSerializer::class.java.name,
"kafka.producers.default.schema.registry.url" to "mock://my-scope-name",
"kafka.consumers.default.schema.registry.url" to "mock://my-scope-name",
"kafka.consumers.default." + KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG to "true"
)
【讨论】:
【参考方案2】:我遇到了类似的问题,并通过 Jackson-Mixin(来自 https://***.com/a/7422285/702345)解决了它。 Avro 似乎生成了 Avro 特定的 Getter 方法,在 Jackson 序列化期间应始终忽略这些方法。
public abstract class JacksonIgnoreAvroPropertiesMixIn
@JsonIgnore
public abstract org.apache.avro.Schema getSchema();
@JsonIgnore
public abstract org.apache.avro.specific.SpecificData getSpecificData();
在 ObjectMapper 上比:
objectMapper.addMixIn(
org.apache.avro.specific.SpecificRecord.class, // Interface implemented by all generated Avro-Classes
JacksonIgnoreAvroPropertiesMixIn.class);
【讨论】:
感谢您的回答。你从哪里得到objectMapper
?
如果你有 spring-boot-starter-web 依赖,它应该已经在你的 Spring-Context 中。否则,只需调用构造函数:new com.fasterxml.jackson.databind.ObjectMapper()
@HaraldBrabenetz 这对我帮助很大!知道我如何仍然可以使用 JsonInclude.Include.NON_NULL 之类的东西吗?响应正在删除空值。【参考方案3】:
杰克逊有时会出现问题。这些错误意味着 Spring Boot 期望的数据与您的结果不同。
您应该返回具有 avro 模式作为属性的对象,如下所示:
class UserResponse extends ResourceSupport
UserData userData;
public void getUserData() ...
然后你在控制器中返回这个:
return new UserResponse();
如果这仍然不适合你,我建议你使用Gson。对于您的应用程序,它看起来像这样:
Gson gson = new Gson();
UserResponse data = new UserResponse();
String json = gson.toJson(data.getUserData());
【讨论】:
以上是关于JsonMappingException:不是地图,不是数组或不是枚举的主要内容,如果未能解决你的问题,请参考以下文章
JsonMappingException:无法初始化代理 - 没有会话
Spring cloud netflix 和 HystrixObservable --> JsonMappingException
使用 Pageable 字段测试端点时出现 JsonMappingException
自定义异常类jackson序列化jsonMappingException异常