Im learning Spring Boot and I made a demo but when I POST a request to add a Object it didn't work!
The error message is:
{ "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/" }
My Entity:
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
My controller:
public class TopicController { @Autowired private TopicService topicService; @RequestMapping(value = "/topics", method = RequestMethod.POST) public void addTopic(@RequestBody Topic topic) { topicService.addTopic(topic); }
My service:
@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); } }
My json:
{ "id": "3", "name": "topic3", "author": "Jessie3", "desc": "T3" }
Please Help !
For deserialisation purposes Topic
must have a zero-arg constructor.
For example:
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 }
This is the default behaviour of the Jackson library.
You need to annotate the constructor with @JsonCreator
:
Marker annotation that can be used to define constructors and factory methods as one to use for instantiating new instances of the associated class.
NOTE: when annotating creator methods (constructors, factory methods), method must either be:
- Single-argument constructor/factory method without
JsonProperty
annotation for the argument: if so, this is so-called "delegate creator", in which case Jackson first binds JSON into type of the argument, and then calls creator. This is often used in conjunction withJsonValue
(used for serialization).- Constructor/factory method where every argument is annotated with either
JsonProperty
orJacksonInject
, to indicate name of property to bind toAlso note that all
JsonProperty
annotations must specify actual name (NOT empty String for "default") unless you use one of extension modules that can detect parameter name; this because default JDK versions before 8 have not been able to store and/or retrieve parameter names from bytecode. But with JDK 8 (or using helper libraries such as Paranamer, or other JVM languages like Scala or Kotlin), specifying name is optional.
Like this:
@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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With