我得到以下错误时,试图获得一个JSON请求和处理它:

jsonmappingexception:没有为类型[简单类型,类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对象的配置参数。我正在使用Spring框架。

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


当前回答

您必须了解Jackson有哪些反序列化选项。在Java中,方法参数名不会出现在编译后的代码中。这就是为什么Jackson通常不能使用构造函数来创建一个定义良好的对象。

如果有一个空构造函数,同时也有setter,它使用空构造函数和setter。如果没有设置,则使用一些黑魔法(反射)来做到这一点。

如果希望在Jackson中使用构造函数,则必须使用@PiersyP在他的回答中提到的注释。您还可以使用构建器模式。如果遇到一些例外,祝你好运。Jackson中的错误处理非常糟糕,很难理解错误消息中的胡言乱语。

其他回答

向所有实体类添加默认构造函数

通常,出现这个错误是因为我们没有创建默认构造函数。 但就我而言: 这个问题只是因为我在父类里面做了used object类。 这浪费了我一整天的时间。

关于上一个版本,我在使用Lombok 1.18时遇到了同样的问题。*产生了问题。

我的解决方案是添加@NoArgsConstructor(不带参数的构造函数),因为@Data默认包含@RequiredArgsConstructor(带参数的构造函数)。

龙目岛Documentation https://projectlombok.org/features/all

这将解决问题:

package example.counter;

import javax.validation.constraints.NotNull;

import lombok.Data;

@Data
@NoArgsConstructor
public class CounterRequest {
    @NotNull
    private final Integer int1;

    @NotNull
    private final Integer int2;
}

我想添加另一个解决方案,不需要一个虚拟构造函数。因为虚拟构造函数有点混乱,因此令人困惑。我们可以提供一个安全的构造函数,通过注释构造函数参数,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) {
        }

}

您必须了解Jackson有哪些反序列化选项。在Java中,方法参数名不会出现在编译后的代码中。这就是为什么Jackson通常不能使用构造函数来创建一个定义良好的对象。

如果有一个空构造函数,同时也有setter,它使用空构造函数和setter。如果没有设置,则使用一些黑魔法(反射)来做到这一点。

如果希望在Jackson中使用构造函数,则必须使用@PiersyP在他的回答中提到的注释。您还可以使用构建器模式。如果遇到一些例外,祝你好运。Jackson中的错误处理非常糟糕,很难理解错误消息中的胡言乱语。