1

I want to be able to pass in data from a POST request and hit my API in which the JSON I pass through binds to the POTD class. Within POTD, I have an ArrayList of type POTDResources, which is where I am having trouble binding the data.

I'm eventually just going to use the entire Problem object, but for right now I am just testing with two fields within the class.

I need the JSON input to be able to bind to an ArrayList of type POTDResources

I'm passing in data like the following:

{
    "problemTitle": "Balancing Binary Tree",
    "resources": [{"name": "youtube", "link": "http://yotube.com"}]
}

The API call first hits:

Controller

@RequestMapping(value = "/generatepotd", method = RequestMethod.POST)
@ResponseBody
public void generatePOTD(@RequestBody POTD problem) throws IOException {

    POTD prob = new POTD();
    prob.setProblemTitle(problem.getProblemTitle());
    prob.setResources(problem.getResources());
    tempGen.generateProblemOfTheDay(prob);
}

POTD Class

    package com.algoq.algoq.models;

    import org.springframework.context.annotation.Description;
    import java.util.ArrayList;

    @Description("Handles the fields required for processing problem of the day")
    public class POTD {
        private String subject;
        private String problemTitle;
        private String problemDescription;
        private ArrayList<POTDResources> resources;

    //    POTD(String subject, String problemTitle, String problemDescription, ArrayList<POTDResources> resources) {
        POTD(String problemTitle, ArrayList<POTDResources> resources) {
    //        this.subject = subject;
            this.problemTitle = problemTitle;
    //        this.problemDescription = problemDescription;
            this.resources = resources;
        }

        public POTD() {

        }

        public String getSubject() {
            return subject;
        }

        public void setSubject(String subject) {
            this.subject = subject;
        }
        public String getProblemTitle() {
            return problemTitle;
        }

        public void setProblemTitle(String problemTitle) {
            this.problemTitle = problemTitle;
        }

        public String getProblemDescription() {
            return problemDescription;
        }

        public void setProblemDescription(String problemDescription) {
            this.problemDescription = problemDescription;
        }

        public ArrayList<POTDResources> getResources() {
            return resources;
        }

        public void setResources(ArrayList<POTDResources> resources) {
            this.resources = resources;
        }
    }

POTD Resource Class

    package com.algoq.algoq.models;

    public class POTDResources {
        private String name;
        private String link;

        public POTDResources(String name, String link) {
            this.name = name;
            this.link = link;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getLink() {
            return link;
        }

        public void setLink(String link) {
            this.link = link;
        }
    }

Error Message

{
    "timestamp": 1513192593064,
    "status": 400,
    "error": "Bad Request",
    "exception": "org.springframework.http.converter.HttpMessageNotReadableException",
    "message": "JSON parse error: Can not construct instance of com.algoq.algoq.models.POTDResources: 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 com.algoq.algoq.models.POTDResources: 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@1710624f; line: 3, column: 17] (through reference chain: com.algoq.algoq.models.POTD[\"resources\"]->java.util.ArrayList[0])",
    "path": "/generatepotd"
}
3
  • Implementation seems fine. What's the error message? Small hint, instead of ArrayList use it by the interface: private List<POTDResources> resources; Also I would try to add default constructors for your Models. Commented Dec 13, 2017 at 19:16
  • @JSONStatham Nice username. I've updated the OP with the error Commented Dec 13, 2017 at 19:17
  • @JSONStatham Looking like the default constructor was necessary.. Still testing. Any idea how Spring actually processes this? Does it look for specific method names, or? Commented Dec 13, 2017 at 19:18

3 Answers 3

2

Your problems lies with the error message:

no suitable constructor found

You are overriding the default constructor, and the ObjectMapper can't create an instance of your Model class.

Try to add a default constructor for POTDResources:

    public POTDResources() {

    }

Jackson, which is used by Spring for JSON and XML processing, can work 2 ways with Object. Constructor and Setter based. If it can find a constructor with the same field names and types, it will try to use that one. If no suitable constructor, then it will try to create an instance of the object, and use setters. You didn't have a suitable constructor and it failed to create the instance.

Sign up to request clarification or add additional context in comments.

Comments

2

Add empty constructor to your POTDResources class:

public POTDResources() {}

The reason being that JSON mapper would first try to initialize your class, and only then would apply values to it

Comments

1

Your problem is that POTDResources does not have a default constructor:

public POTDResources() {}

Jackson requires a no-arg constructor.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.