JsonMappingException:找不到types为的合适构造函数:无法从JSON对象实例化

试图获取JSON请求并处理它时,出现以下错误:

org.codehaus.jackson.map.JsonMappingException:找不到types为[简单types,类com.myweb.ApplesDO]的合适构造函数:无法从JSON对象实例化(需要添加/启用types信息?)

这是我试图发送的JSON:

{ "applesDO" : [ { "apple" : "Green Apple" }, { "apple" : "Red Apple" } ] } 

在控制器中,我有以下方法签名:

 @RequestMapping("showApples.do") public String getApples(@RequestBody final AllApplesDO applesRequest){ // Method Code } 

AllApplesDO是ApplesDO的一个包装:

 public class AllApplesDO { private List<ApplesDO> applesDO; public List<ApplesDO> getApplesDO() { return applesDO; } public void setApplesDO(List<ApplesDO> applesDO) { this.applesDO = applesDO; } } 

ApplesDO:

 public class ApplesDO { private String apple; public String getApple() { return apple; } public void setApple(String appl) { this.apple = apple; } public ApplesDO(CustomType custom){ //constructor Code } } 

我认为jackson无法将JSON转换为Java对象的子类。 请帮助Jackson的configuration参数将JSON转换为Java对象。 我正在使用Spring框架。

编辑:包括在上面的示例类中导致此问题的主要错误 – 请看看接受答案的解决scheme。

所以,最后我意识到了什么是问题。 我怀疑这不是jackson的configuration问题。

其实问题出在ApplesDO类:

 public class ApplesDO { private String apple; public String getApple() { return apple; } public void setApple(String apple) { this.apple = apple; } public ApplesDO(CustomType custom) { //constructor Code } } 

有一个为类定义的自定义构造函数使其成为默认的构造函数。 引入一个虚拟构造函数已经使错误消失了:

 public class ApplesDO { private String apple; public String getApple() { return apple; } public void setApple(String apple) { this.apple = apple; } public ApplesDO(CustomType custom) { //constructor Code } //Introducing the dummy constructor public ApplesDO() { } } 

发生这种情况的原因如下:

  1. 你的内部类应该被定义为静态的

     private static class Conditiont { //jackson specific } 
  2. 这可能是你的类没有默认的构造函数( 更新:这似乎并非如此)

     private static class Condition { private Long id; public Condition() { } // Setters and Getters } 
  3. 这可能是你的安装人员没有正确定义或不可见(例如私人安装者)

我想添加另一个解决scheme,这不需要一个虚构的构造函数。 由于虚拟构造器有点混乱,随后混乱。 我们可以提供一个安全的构造函数,并通过注释构造函数参数来允许jackson确定构造函数参数和字段之间的映射关系。

所以下面也会起作用。 注意注释中的string必须与字段名称匹配。

 import com.fasterxml.jackson.annotation.JsonProperty; public class ApplesDO { private String apple; public String getApple() { return apple; } public void setApple(String apple) { this.apple = apple; } public ApplesDO(CustomType custom){ //constructor Code } public ApplesDO(@JsonProperty("apple")String apple) { } } 

当我遇到这个问题的时候,就是试图用内部类来作为DO的结果。 内部类的构造(默默地)需要一个封闭类的实例 – 这对jackson是不可用的。

在这种情况下,将内部类移到它自己的.java文件中解决了这个问题。

你可以请testing这个结构。 如果我没有记错,可以这样使用它:

 { "applesRequest": { "applesDO": [ { "apple": "Green Apple" }, { "apple": "Red Apple" } ] } } 

其次,请添加默认的构造函数,每个类也可能有所帮助。

Thumb规则 :为每个用作映射类的类添加一个默认构造函数。 你错过了这个问题出现!
只需添加默认构造函数,它应该工作。

如果您开始注释构造函数,则必须注释所有字段。

注意,我的Staff.name字段被映射到JSONstring中的“ANOTHER_NAME”。

  String jsonInString="{\"ANOTHER_NAME\":\"John\",\"age\":\"17\"}"; ObjectMapper mapper = new ObjectMapper(); Staff obj = mapper.readValue(jsonInString, Staff.class); // print to screen public static class Staff { public String name; public Integer age; public Staff() { } //@JsonCreator - don't need this public Staff(@JsonProperty("ANOTHER_NAME") String n,@JsonProperty("age") Integer a) { name=n;age=a; } } 

你必须意识到jackson可用于反序列化的选项。 在Java中,方法参数名称在编译的代码中不存在。 这就是为什么jackson通常不能使用构造函数来创build一个定义好的对象的一切已经设置。

所以,如果有一个空的构造函数,也有setter,它使用空的构造函数和设置器。 如果没有安装者,则使用一些黑魔法(reflection)来实现。

如果你想用Jackson的构造函数,你必须使用@PiersyP在他的答案中提到的注释。 您也可以使用生成器模式。 如果遇到一些例外,祝你好运。 在jackson的error handling很糟糕,很难理解错误信息中的乱码。

您必须在我们的模型类中创build虚拟空构造函数。因此,在映射json时,它通过setter方法进行设置。

定制jackson序列化器/解串器失败也可能是问题。 虽然不是你的情况,但值得一提的是。

我面临着同样的例外,情况就是如此。