未找到接口 java.util.List Rest API Spring boot 的主构造函数或默认构造函数

Posted

技术标签:

【中文标题】未找到接口 java.util.List Rest API Spring boot 的主构造函数或默认构造函数【英文标题】:No primary or default constructor found for interface java.util.List Rest API Spring boot 【发布时间】:2019-07-06 21:11:38 【问题描述】:

我正在将请求正文传递给邮递员的 POST 请求,类似于:

 "name":"Mars",
"artifacts":[
   
      "elements":[
         
            "name":"carbon",
            "amount":0.5,
            "measurement":"g"
         
      ],
      "typeName":"typeA"
   ,
   
      "elements":[
         
            "name":"hydrogen",
            "amount":0.2,
            "measurement":"g"
         
      ],
      "typeName":"typeB"
   
]

rest 控制器中的 create 方法如下所示。

  @RequestMapping("/create")
  public Planet create(@RequestBody Planet data) 
      Planet mars = planetService.create(data.getName(),data.getArtifacts());
      return mars;

Planet 及其所有嵌套对象都有一个默认构造函数,例如:

public Planet() 

但是,由于缺少默认构造函数,我无法创建新的行星对象。请帮忙!

编辑: 行星类

public class Planet 
@JsonProperty("name")
private String name;
@Field("artifacts")
private List<Artifact> artifacts;

public Planet() 

public Planet(String name, List<Artifact> artifacts)

this.name = name;
this.artifacts = artifacts;

//setters and getters


工件类:

public class Artifact() 
@Field("elements")
private List<Element> elements;
@JsonProperty("typeName")
private String typeName;

public Artifact() 

public Artifact(String typeName, List<Element> elements)

this.typeName = typeName;
this.elements = elements;


元素类:

public class Element() 
@JsonProperty("elementName")
private String name;
@JsonProperty("amount")
private double amount;
@JsonProperty("measurement")
private String measurement;

public Element() 

public Element(String name, double amount, String measurement)

//assignments


【问题讨论】:

你能发布 Planet.java 吗? 完成,发布简化版 【参考方案1】:

当我忘记参数之前的@RequestBody 时,我遇到了同样的错误

  @RequestMapping("/create")
  public Planet create(@RequestBody Planet data) 

【讨论】:

就是这样!我忘了添加注释,我花了几分钟摸了摸头,不知道发生了什么,但最终我可以解决。【参考方案2】:

我猜,它试图调用没有构造函数的new List()。尝试在您的签名中使用new ArrayList&lt;&gt;()

如果它以这种方式工作,您已经发现了错误。然后重新考虑调用方法的概念,因为您通常希望避免在方法签名中使用 List 的实现

【讨论】:

谢谢你这工作,但在创建的对象中得到了一些奇怪的字符串。 这只是对您在该主题中的问题的准确回答。正如我所说,你应该重新考虑你的概念。这里已经有几个答案会有所帮助【参考方案3】:

我不明白你面临的问题是什么,但我可以立即看到一个错误,所以猜测这是你面临的问题,我会给你一个解决方案。

创建一个与您的 json 数据结构匹配的类,如下所示:

Class PlanetData 
    private String name;
    private List<Planet> artifacts;

    public PlanetData(String name, List<Planet> artifacts)
        name = name;
        artifacts = artifacts;
    

    // include rest of getters and setters here.

那么你的控制器应该是这样的。基本上,您需要将 @RequestBody 放入您希望从请求 JSON 接收的所有参数中。之前您只将 @RequestBody 放入名称参数而不是工件参数,并且由于请求正文只能使用一次,因此您需要一个包装类来使用单个 @RequestBody 注释接收完整的请求正文。

@RequestMapping("/create")
  public String create(@RequestBody PlanetData data) 
      Planet mars = planetService.create(data.getName(),data.getArtifacts());
      return mars.toString();
  

编辑:查看 Planet 类,它还需要一些修改

public class Planet 
private String typeName; // key in json should match variable name for proper deserialization or you need to use some jackson annotation to map your json key to your variable name.
private List<Element> elements;

public Planet() 

public Planet(String typeName, List<Element> elements)

this.typeName = typeName;
this.elements = elements;

//setters and getters. Remember to change your setters and getter from name to typeName.


希望这能解决您的问题。

【讨论】:

谢谢,这有帮助!我得到无法构造com.Planet 的实例(尽管至少存在一个创建者):没有字符串参数构造函数/工厂方法可以从字符串值('name')反序列化;嵌套异常是 com.fasterxml.jackson.databind.exc.MismatchedInputException 这是因为在您的 Json 中,对于 Planet 信息,您的密钥是 typeName,而不是 name,但在您的 Planet 类中,您将其保留为 name。检查我答案的最后一部分,我已将您的 Planet 课程中的 name 更改为 typeName。另外,如果这有帮助,请将其标记为答案。谢谢 typeName 属于 Artifact 类 你为什么要更改这么多课程的名称和内容。早些时候,您的 Planet 类包含名称和元素,现在它包含名称和工件。请最后一次编辑您的问题,以便我可以将我的答案与您的实际课程保持一致,否则我们都会感到困惑。添加隐藏所有 getter 和 setter 的所有类代码。 抱歉给您带来了困惑,我现在改了。感谢您的帮助【参考方案4】:

你应该写如下:

...
public String create(@RequestBody JSONObject requestParams) 
      String name=requestParams.getString("name");
      List<Planet> planetArtifacts=requestParams.getJSONArray("artifacts").toJavaList(Planet.Class);
...

【讨论】:

嗨,我认为最好有一个包装类来接收您的请求正文。这种方式 API 契约非常干净和清晰,因为没有人必须通过您的服务来实际确定 API 期望什么。你怎么看?

以上是关于未找到接口 java.util.List Rest API Spring boot 的主构造函数或默认构造函数的主要内容,如果未能解决你的问题,请参考以下文章

Java进阶--List接口

Java之List

Java自学-集合框架 List接口

java.util.list

java.util.List接口的方法subList()进行分页查询

错误:java.lang.NullPointerException:尝试在空对象引用上调用接口方法“int java.util.List.size()”