Java Jackson InvalidDefinitionException:无法构造实例,因为找不到默认的无参数构造函数
我有一个应用程序,它使用SpringBoot提供REST功能。将POST响应反序列化为POJO时遇到问题。例外情况如下:Java Jackson InvalidDefinitionException:无法构造实例,因为找不到默认的无参数构造函数,java,spring-boot,jackson-databind,Java,Spring Boot,Jackson Databind,我有一个应用程序,它使用SpringBoot提供REST功能。将POST响应反序列化为POJO时遇到问题。例外情况如下: org.springframework.http.converter.HttpMessageConversionException: Type definition error: [collection type; class uci.BoundedList, contains [simple type, class java.lang.Object]]; nested ex
org.springframework.http.converter.HttpMessageConversionException: Type definition error: [collection type; class uci.BoundedList, contains [simple type, class java.lang.Object]]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `uci.BoundedList` (no Creators, like default construct, exist): no default no-arguments constructor found
BoundedList
类型是使用XJC从XML模式生成的API的一部分。我无法控制这个类是如何生成的。事实证明,它是java.util.ArrayList
的一个子类,并且只定义了一个构造函数:
public BoundedList(int minOccurs, int maxOccurs) {
super();
this.minOccurs = minOccurs;
this.maxOccurs = maxOccurs;
}
它没有定义无参数构造函数,这正是异常所抱怨的
既然我不能修改这个类,而且它是我正在使用的API的一个组成部分,那么我该如何解决这个问题呢?我可以提供某种定制类/接口来满足Jackson数据绑定吗?还有其他可能的解决办法吗
更新:
根据下面提供的答案,我尝试了一些建议。它们都不起作用。我正在调查“混合”方法,我承认我不太明白它应该如何工作。我读过的许多文章都写得很简单,但似乎还是有点“黑魔法”
在任何情况下,以下是我根据所读内容尝试做的一些片段:
“混合”类:
添加到现有配置类的内容:
@Configuration
@EnableAsync
@EnableScheduling
@ComponentScan("<package>")
public class ServiceConfigurer {
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper mapper = builder.createXmlMapper(false).build();
mapper.addMixIn(BoundedList.class, BoundedListMixin.class);
return mapper;
}
}
我还是有同样的问题。这个问题必须与其他问题有关
注意:
我还应该澄清,当我调用GET
时,这个问题就表现出来了。我有一个简单的REST端点,它只请求服务返回POJO。奇怪的是,如果我从浏览器发送请求,该对象将作为JSON返回并呈现。但是,当从代码中调用它时,我得到了上面的异常
获取呼叫:
RequestStatus statusMsg = template.getForObject("http://localhost:8080/rst/missionPlanning/data", RequestStatus.class);
最简单的方法是向POJO添加Jackson注释,以指示如何反序列化。描述得很好 但是,由于POJO是自动生成的,您无法修改它,因此还有两个其他选项:
您可以将其映射到其他类型,然后将其转换为一个有界列表。Jackson需要一个默认构造函数,该构造函数的参数上没有参数或注释,以确定JSON对象中的哪个字段应该映射到参数。大概是这样的:
@JsonCreator
public BoundedList(@JsonProperty("min") int minOccurs, @JsonProperty("max") int maxOccurs) {
// your code
}
如果无法更改类,则可以使用Jackson MixIns
abstract class MixIn {
MixIn(@JsonProperty("min") int minOccurs, @JsonProperty("max") int maxOccurs) { }
}
并在对象映射器上进行如下配置:
objectMapper.addMixInAnnotations(BoundedList.class, MixIn.class);
有关详细信息,请参阅。您建议的“混合”方法(也由下面的@Mike建议)听起来非常有趣,似乎可以解决我的问题。但我不确定的是,它似乎是在Jackson
ObjectMapper
上注册的。在我的情况下,我没有明确使用ObjectMapper。我正在使用restemplate
发出POST
请求,返回的对象就是问题发生的地方(至少我是这么认为的)。我(可以吗?)如何让ObjectMapper(以及混合)参与其中?下面是调用:ResponseEntity response=template.postForEntity(“http://localhost:8080/rst/missionPlanning/generateRoute,实体,CommandStatus.class)你可以在这里找到一个例子:(可能你会发现更多的谷歌搜索)。其思想是注册自己的ObjectMapperbean。Spring Boot可以帮你解决这个问题。我试着按照建议去做(实际上是根据我通过谷歌搜索发现的几种不同的方法),但它们似乎都不起作用。我仍然得到同样的例外(这里有一个链接似乎非常适合我的情况。但是它仍然不起作用。
abstract class MixIn {
MixIn(@JsonProperty("min") int minOccurs, @JsonProperty("max") int maxOccurs) { }
}
objectMapper.addMixInAnnotations(BoundedList.class, MixIn.class);