我正在学习Spring Boot并且我做了一个演示,但是当我发布一个添加对象的请求时,它没有工作!
错误消息是:
{
"timestamp": 1516897619316,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "JSON parse error: Can not construct instance of io.starter.topic.Topic: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of io.starter.topic.Topic: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)\n at [Source: java.io.PushbackInputStream@1ff3f09a; line: 2, column: 9]",
"path": "/topics/"
}
我的实体:
的
的public class Topic {
private String id;
private String name;
private String author;
private String desc;
public Topic(String id, String name, String author, String desc) {
this.id = id;
this.name = name;
this.author = author;
this.desc = desc;
}
//getters and setters
的
我的控制器:
的
的public class TopicController {
@Autowired
private TopicService topicService;
@RequestMapping(value = "/topics", method = RequestMethod.POST)
public void addTopic(@RequestBody Topic topic) {
topicService.addTopic(topic);
}
的
我的服务:
的
的@Service
public class TopicService {
private List<Topic> topics = new ArrayList<>(Arrays.asList(
new Topic("1", "topic1", "Martin", "T1"),
new Topic("2", "topic2", "Jessie", "T2")
));
public void addTopic(Topic topic) {
topics.add(topic);
}
}
的
我的json:
{
"id": "3",
"name": "topic3",
"author": "Jessie3",
"desc": "T3"
}
请帮助!
答案 0 :(得分:13)
对于反序列化目的,Topic
必须具有零参数构造函数。
例如:
public class Topic {
private String id;
private String name;
private String author;
private String desc;
// for deserialisation
public Topic() {}
public Topic(String id, String name, String author, String desc) {
this.id = id;
this.name = name;
this.author = author;
this.desc = desc;
}
// getters and setters
}
这是Jackson库的默认行为。
答案 1 :(得分:4)
您需要使用@JsonCreator
注释构造函数:
标记注释,可用于将构造函数和工厂方法定义为用于实例化关联类的新实例的注释。
注意:在注释创建者方法(构造函数,工厂方法)时,方法必须是:
- 参数没有
JsonProperty
注释的单参数构造函数/工厂方法:如果是,这就是所谓的“委托创建者”,在这种情况下,Jackson首先将JSON绑定到参数的类型,然后调用创造者。这通常与JsonValue
(用于序列化)一起使用。- 构造函数/工厂方法,其中每个参数都使用
JsonProperty
或JacksonInject
进行注释,以指示要绑定到的属性的名称另请注意,除非您使用可以检测参数名称的扩展模块之一,否则所有
JsonProperty
注释都必须指定实际名称(“默认”为非空字符串)。这是因为8之前的默认JDK版本无法从字节码存储和/或检索参数名称。但是使用JDK 8(或使用Paranamer等辅助库或Scala或Kotlin等其他JVM语言),指定name是可选的。
像这样:
@JsonCreator
public Topic(@JsonProperty("id") String id, @JsonProperty("name") String name,
@JsonProperty("author") String author, @JsonProperty("desc") String desc) {
this.id = id;
this.name = name;
this.author = author;
this.desc = desc;
}