JsonMappingException:找不到类型[simple type,class]的合适构造函数:无法从JSON对象实例化

问题

尝试获取JSON请求并处理它时,我收到以下错误:

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

这是我要发送的JSON:

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

在Controller中,我有以下方法签名:

@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将JSON转换为Java Objects的配置参数。我正在使用Spring Framework。

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


#1 热门回答(501 赞)

所以,最后我意识到问题是什么。我怀疑这不是杰克逊的配置问题。

实际问题是在ApplesDOClass:

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() {
    }

}

#2 热门回答(336 赞)

出现这种情况的原因如下:

  • 你的内部类应该定义为静态私有静态类Condition {// jackson specific
    }
  • 可能是你的类中没有默认构造函数(UPDATE:似乎不是这种情况)private static class Condition {
        私人长身份;

    public Condition(){
    }

    // Setters和Getters
}

  • 可能是你的Setter未正确定义或不可见(例如私人制定者)

#3 热门回答(54 赞)

我想为此添加另一个不需要虚拟构造函数的解决方案。因为虚拟构造函数有点混乱并且随后令人困惑。我们可以提供一个安全的构造函数,并通过注释构造函数参数,我们允许jackson确定构造函数参数和字段之间的映射。

所以以下也会奏效。请注意,注释中的字符串必须与字段名称匹配。

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) {
        }

}