0

I am getting json using rest templete

  RestTemplate restTemplate = new RestTemplate();
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
 test = restTemplate.getForObject(url,Test.class, params);

I am getting json like

{"object":"{\"id\":123,\"userId\":159,\"contentId\":1}"}

Here is my POJO

@JsonIgnoreProperties(ignoreUnknown = true)
public class Test {
    @JsonProperty("id")
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

But I am getting error

[Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@9bd513b; line: 1, column: 75] (through reference chain: nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.soham.Test] from String value ('{"id":123,"userId":116,"contentId":0}'); no single-String constructor/factory method

Update: I have tried to add a constructor

public Test(String id){
this.id=id;
}

It's not showing the error then.But it's printing the whole json

{"id":123,"userId":116,"contentId":0}

How to solve?Any idea?

Soham
  • 4,397
  • 11
  • 43
  • 71
  • Error message states it clear I guess - furthermore, quite a few duplicates here on SO like [this f.e](http://stackoverflow.com/questions/25192342/jackson-json-no-single-string-constructor-factory-method-error-on-unmarshal) – Roman Vottner Jun 04 '15 at 20:18
  • @RomanVottner See my update answer.But the question you mentioned has no accepted answer – Soham Jun 04 '15 at 20:20
  • You can try [this approach](http://stackoverflow.com/questions/8369260/jackson-throws-jsonmappingexception-on-deserialize-demands-single-string-constr) – Roman Vottner Jun 04 '15 at 20:26
  • @RomanVottner .I would prefer if it can be mapped by POJO . I would like to avoid use of objectMapper – Soham Jun 04 '15 at 20:33
  • Seems like you should add a [wrapper class](http://forum.spring.io/forum/spring-projects/android/92448-examples-to-make-resttemplate-work-with-json) – Roman Vottner Jun 04 '15 at 20:42
  • @RomanVottner Can you explain more. – Soham Jun 04 '15 at 20:53
  • What should I explain? I'm not sure if you've defined a message converter (for JSON in particular) as this should be enough to return a POJO, in relation to the posted spring.io thread. Following the thread further, OneWorld123 solved his JSON to POJO issue via a wrapper class, though he did not define any message converters at all. As you did not post your Spring restTemplate definition its a guessing-game – Roman Vottner Jun 04 '15 at 21:02
  • @RomanVottner See my updated question. – Soham Jun 04 '15 at 21:04
  • the wrapper could be something like [this](http://pastebin.com/YVTct0Br). Something maybe has to map to the "object" key in your json. – Alper Akture Jun 04 '15 at 23:18

3 Answers3

0

Just taking the sample URL from the Getting Started restTemplate page and using the following code works pretty fine in my case:

Maven pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>at.rovo.test</groupId>
    <artifactId>RestTemplate</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>RestTemplate</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.3.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
</project>

Bean-Class:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Test
{
    @JsonProperty("id")
    private long id;
    private String name;
    private String about;
    private String phone;
    private String website;

    public Test()
    {

    }

    public void setId(long id)
    {
        this.id = id;
    }

    public long getId()
    {
        return this.id;
    }

    public String getName()
    {
        return name;
    }

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

    public String getAbout()
    {
        return about;
    }

    public void setAbout(String about)
    {
        this.about = about;
    }

    public String getPhone()
    {
        return phone;
    }

    public void setPhone(String phone)
    {
        this.phone = phone;
    }

    public String getWebsite()
    {
        return website;
    }

    public void setWebsite(String website)
    {
        this.website = website;
    }
}

And last but not least the class specifying the restTemplate which also invokes the restTemplate with a given URL (taken from the getting started page) and prints a couple of properties to the console:

import java.util.ArrayList;
import java.util.List;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;

public class App 
{
    public static void main( String[] args )
    {
        RestTemplate restTemplate = new RestTemplate();
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
        messageConverters.add(new FormHttpMessageConverter());
        messageConverters.add(new StringHttpMessageConverter());
        messageConverters.add(new MappingJackson2HttpMessageConverter());
        restTemplate.setMessageConverters(messageConverters);

        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
        String url = "http://graph.facebook.com/pivotalsoftware";
        Test response = restTemplate.getForObject(url, Test.class);

        System.out.println("Id: " + response.getId());
        System.out.println("Name: " + response.getName());
        System.out.println("Phone: " + response.getPhone());
        System.out.println("About: " + response.getAbout());
    }
}
Roman Vottner
  • 12,213
  • 5
  • 46
  • 63
  • am using spring-boot,so I didn't need maven dependency for jackson. Though I was not able to solve it,it is giving the same error. – Soham Jun 05 '15 at 12:43
0

From my experience with Spring REST, the constructor of entity objects (in this case your Test class) should take no parameter. Seeing Roman Vottner's response seems to provide confirmation of that.

Yoshimitsu
  • 65
  • 1
  • 9
0

I am able to solve it.Here is my solution

    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonAutoDetect(creatorVisibility = JsonAutoDetect.Visibility.ANY)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public class Test {

        @JsonProperty("id")
        private String id;
        @JsonProperty("userId")
        private int userId;
        @JsonProperty("contentId")
        private int contentId;
       public Test() {

    }

    @JsonCreator
    public static Test getJson(String json) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(json, Test.class);
    }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }
        public String getContentId() {
            return contentId;
        }

        public void setContentId(String contentId) {
            this.contentId = contentId;
        }
         public int getUserId() {
            return userId;
        }

        public void setUserId(int userId) {
            this.userId = userId;
        }
    }
Soham
  • 4,397
  • 11
  • 43
  • 71