RestTemplate can't fetch JSONObject
Asked Answered
I

2

11

I can't fetch JSONObject directly, this code works:

RestTemplate restTemplate = new RestTemplate();
String str = restTemplate.getForObject("http://127.0.0.1:8888/books", String.class);
JSONObject bookList = new JSONObject(str);

but this code doesn't:

JSONObject bookList = restTemplate.getForObject("http://127.0.0.1:8888/books", JSONObject.class);

What could be the problem? It doesn't give errors but I've an empty JSONObject in the end.

my pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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>com.example</groupId>
    <artifactId>library-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>LibraryClient</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

and I have to add a bit more details you can see when I use a string to cast inbetween it works. and a bit more details, maybe I should delete my pom.xml to reduce the amount of code in this question, would that make sense? | Okay more?

Inweave answered 25/1, 2017 at 11:1 Comment(1)
Are you trying to read an XML file using an object that expects a JSON formatted source?Contextual
C
11

RestTemplate will use reflection in order to create the resulting object

When you use restTemplate.getForObject it will try to use the default constructor of the class you pass and then tries to fill all its fields In this case it doesn't know how to create the JSONObject

In order to do it you must:

  • use your own HttpMessageConverterExtractor
  • use the second approach JSONObject bookList = new JSONObject(str);
Cirone answered 25/1, 2017 at 12:18 Comment(2)
You would think this would throw an exception like in other languages instead of failing silently.Orenorenburg
@Orenorenburg If that were the case, RestTemplate would literally throw in 99% of its use cases, making it completely useless. Whenever the response would contain an additional property that you do not wish to instantiate in your response DTO, the parsing would fail with an exception. The problem is that the above code is not invalid, but OP understood incorrectly what it should do. It is almost like saying that int eight = three + five should throw an exception if the result is not eight. This is why we have documentation and unit tests, to reduce bugs introduced by the developer.Moncton
M
2

I assume you do not specifically need javax.json.JSONObject, but rather any generic JSON object tree.

Your POM has jackson-databind, which makes RestTemplate (and Spring Web in general) work with com.fasterxml.jackson.databind.JsonNode.

So, this will work:

JsonNode bookList = restTemplate.getForObject("http://127.0.0.1:8888/books", JsonNode.class);

int count = bookList.get("count").asInt(); // Null check omitted.
Marshmallow answered 11/10, 2022 at 9:51 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.