JsonMappingException:没有找到合适的构造函数类型[简单类型,类]:不能从JSON对象实例化



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

org.codehaus.jackson.map。JsonMappingException:没有找到适合类型[简单类型,类com.myweb]的构造函数。:不能从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 Framework。

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

所以,我终于意识到问题是什么了。这不是我所怀疑的Jackson配置问题。

实际上问题在ApplesDO Class:

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. 内部类应该定义为static

    private static class Condition {  //jackson specific    
    }
    
  2. 这可能是你没有默认的构造函数在你的类(UPDATE:这似乎不是这种情况)

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

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

当我遇到这个问题时,这是试图使用内部类作为DO的结果。内部类的构造(静默的)需要一个封闭类的实例——这对于Jackson来说是不可用的。

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

通常,出现此错误是因为我们没有创建默认构造函数
但在我的情况下:
这个问题的出现仅仅是因为我在父类中使用了对象类。
这浪费了我一整天的时间。

经验法则:为您用作映射类的每个类添加默认构造函数。你错过了这一点,问题出现了!
只需添加默认构造函数,它就可以工作了。

您能测试一下这个结构吗?如果我没记错的话,你可以这样用:

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

第二,请为每个类添加默认构造函数,这也可能有所帮助。

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

关于上次发布,我在使用Lombok 1.18时遇到了同样的问题。*生成问题。

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

lombok文档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;
}

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

注意,我的Staff.name字段映射到JSON字符串中的"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一般不能使用构造函数来创建一个定义良好的对象。

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

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

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

自定义jackson序列化器/反序列化器失败也可能是问题所在。虽然这不是你的情况,但还是值得一提。

我遇到了同样的异常,情况就是这样。

对于我来说,这曾经是有效的,但是升级库导致这个问题出现。问题是有这样一个类:

package example.counter;
import javax.validation.constraints.NotNull;
import lombok.Data;
@Data
public class CounterRequest {
    @NotNull
    private final Integer int1;
    @NotNull
    private final Integer int2;
}
使用lombok:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.0</version>
</dependency>

回到

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.10</version>
</dependency>

修复了这个问题。不知道为什么,但想记录下来以备将来使用

相关内容

  • 没有找到相关文章

最新更新