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() { } }
发生这种情况的原因如下:
-
你的内部类应该被定义为静态的
private static class Conditiont { //jackson specific }
-
这可能是你的类没有默认的构造函数( 更新:这似乎并非如此)
private static class Condition { private Long id; public Condition() { } // Setters and Getters }
-
这可能是你的安装人员没有正确定义或不可见(例如私人安装者)
我想添加另一个解决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序列化器/解串器失败也可能是问题。 虽然不是你的情况,但值得一提的是。
我面临着同样的例外,情况就是如此。