Link to home
Start Free TrialLog in
Avatar of SheppardDigital
SheppardDigital

asked on

Java object not being converted to JSON

Hi,

I'm sure this is a simple issue but I can't figure it out.

I have an object which I'm trying to return to the browser in JSON format, but for some reason the response I seem to be getting is a reference to the object rather than the object itself;

{"client":"model.Client@3eb1cf31"}

Open in new window


The code I'm using the generate the response is;

@GET
	@Produces("application/json")
	public Response get() {
		Client client = this.clientRepo.get(1);
		
		JSONObject response = new JSONObject();
		response.put("client", client);
		
		return Response.status(200).entity(response.toString()).build();
	}

Open in new window


However, if I put the object inside hashmap and then add the hashmap to the JSON object, the object is converted to JSON just fine.

@GET
	@Produces("application/json")
	public Response get() {
		Client client = this.clientRepo.get(1);
		
		HashMap r = new HashMap();
		r.put("client", client);
		
		JSONObject response = new JSONObject();
		response.put("response", r);
		
		return Response.status(200).entity(response.toString()).build();
	}

Open in new window


Obviously I could just use the hashmap method, but it seems like an unnecessary step.

Can anyone pin point why the first example doesn't work?

Thanks
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

You do of course need to cast the object placed into the response. You're doing that?
Avatar of srikotesh
srikotesh

u need type cast the object into client type

after casting ur object
do this
Response<Client> response = new Response<>();
if(client != null){
response.setSuccess(client );
}esle{
response.setWaring("no records");
}
Avatar of SheppardDigital

ASKER

I'm casting the object when it's pulled from the database. Here's the method that returns the client object.

public Client get(Integer clientId) {
		Client client;
		
		try {
			Query query = this.entityManager.createQuery("SELECT c FROM Client c WHERE id = :id");
			client = (Client) query.setParameter("id", clientId).setMaxResults(1).getSingleResult();
		}
		catch (NoResultException e) {
			client = new Client();
		}
		finally {
			this.close();
		}
		
		return client;
	}

Open in new window


I've also tried casting the object as it's put into the response;

@GET
	@Produces("application/json")
	public Response get() {
		Client client = this.clientRepo.get(1);
		
		JSONObject response = new JSONObject();
		response.put("client", (Client) client);
		
		return Response.status(200).entity(response.toString()).build();
	}

Open in new window

I seem to be getting is a reference to the object rather than the object
That output is like that because Client does not override toString
As you can tell, I'm pretty new to Java.

I don't really understand your comment, are you saying that the Client needs to have a toString() method which converts returns JSON?

Why does it work in the Client is in a HashMap or Collection? is it because they have their own toString() methods to handle the conversion?
Please post the output found when it IS in a Map/Collection
Output when I put the Client in a HashMap;

{"response":{"client":{"name":"Some company","id":1}}}

Open in new window


and here's the code to do it;

@GET
	@Produces("application/json")
	public Response get() {
		Client client = this.clientRepo.get(1);
		
		HashMap r = new HashMap();
		r.put("client", client);
		
		JSONObject response = new JSONObject();
		response.put("response", r);
		
		return Response.status(200).entity(response.toString()).build();
	}

Open in new window

Not quite sure why that happens, as i don't know the APIs
What IS that API btw?
Hi CEHJ,
that is hibernate, JPA implementation.

Hi Sheppard,
this part also looks good

Query query = this.entityManager.createQuery("SELECT c FROM Client c WHERE id = :id");
client = (Client) query.setParameter("id", clientId).setMaxResults(1).getSingleResult();

i think while setting this object of type client in @get method having issue.
while setting u r setting it map object.
instead of that

in response model class create one method which will set dirly object .
response.setSuccess(client);
Hi srikotesh

Sorry, I don't fully understand what you're asking me to try?
@GET
	@Produces("application/json")
	public Response get() {
		Client client = this.clientRepo.get(1);
		
		JSONObject response = new JSONObject();
		response.put("client", client);//here instead of put do like
                response.setSuccess(urobject);
		
		return Response.status(200).entity(response.toString()).build();
	}

Open in new window

The setSuccess method doesn't seem to exist on the response object.
u have to create response model class separately and create method which will take object as parameter.
Firstly, I too am not sure why your Hashmap version is working the way it is. Something funky is going on there, that I can't get my head around.

Anyway, I guess the point of the matter is that JSONObject is not meant to do what you are trying to make it do. You are trying to get it to automatically "map" your Client POJO to a JSON string. All JSONObject is there to do is "hold" the JSON representation of an object but in an object rather than a string. You would need other libraries to do that for you such as (Jackson, Gson, and probably many others).

I am less familiar with JAX-RS API's that you are using, but my thought on the subject is that you shouldn't even need the JSONObject representation for this to work like you want it. I could be way off, but have you tried something like this code...

@GET
	@Produces("application/json")
	public Response get() {
		Client client = this.clientRepo.get(1);
		
		return Response.status(200).entity(client).build();
	}

Open in new window


You may need to explicitly add the required libraries to allow the automatic marshalling of object to JSON (which you would need with whatever way you end up going). If you need help determining what libraries these are, you will need to tell us what JAX-RS implementation you are using, and also it would help if you tell us what (if any) dependency manager you are using, eg. maven, ivy, gradle, etc.
Hi mccarl,

Thanks for the feedback.

I don't really get that JSONObject is meant to hold your objects before conversion, if that was the case then surely using a HashMap would result it exactly the same output.

I was under the impression that the JSONObject is where you'd store the data to be converted to JSON, and later have it returned as JSON by the JSONObject. However, as mentioned previously, I'm pretty new to Java having worked with PHP for the last 15 years.

I'm using the Maven dependency manager, and below are the contents;

<dependencies>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.19</version>
</dependency>
<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.0.1.Final</version>
        </dependency>
        <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.4</version>
</dependency>
</dependencies>

Open in new window

Did you try the code I posted above?

If it doesn't work straight up, perhaps "jersey" doesn't automatically use Jackson. There appears to be a jersey-json dependency that you could try adding to your maven pom.xml that might just make it work as it should.
Hi,

Yes I tried the code above, and sadly it was still doing exactly the same.

Instead of using a JSONObject to hold the response data, I'm putting it in a hashmap and returning the hashmap, this seems to work perfectly and ends up being roughly the same amount of code.

public HashMap get() {
     HashMap response = new HashMap();
     response.put("client", this.clientRepo.get(1));

     return response;
}

Open in new window


I still don't know why simply returning the client doesn't work.
ASKER CERTIFIED SOLUTION
Avatar of mccarl
mccarl
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Should have added to the above...

So then in a browser, I navigated to http://localhost:9696/server/client

and received this
{"id":-1,"name":"Some company"}

Open in new window