未找到接口 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<>()
。
如果它以这种方式工作,您已经发现了错误。然后重新考虑调用方法的概念,因为您通常希望避免在方法签名中使用 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.util.List接口的方法subList()进行分页查询
错误:java.lang.NullPointerException:尝试在空对象引用上调用接口方法“int java.util.List.size()”