JAX-RS service response is returning double fields without decimal places

1k views Asked by At

I'm working on a JAX-RS web service that returns a POJO as a JSON. The POJO contains double and integer fields. The problem is whenever the double fields are whole numbers(eg - 3.0, 22.0 etc), the corresponding fields in the returned JSON does not contain the decimal point. The decimal places are preserved for non-whole numbers(3.53, 22.2343 etc).

I want the service interface to be uniform so that the double fields always have a decimal point. Why does the returned JSON not have decimal points for whole numbers and how do I fix that?

Here is the code for the operation:

import javax.ws.rs.core.Response;
@GET
@Path("/testjson")
@Produces({ MediaType.APPLICATION_JSON})
public Response testJSON() {
    ParentClass parentClass = new ParentClass();
    ChildClass childClass = new ChildClass();
    parentClass.childClass = childClass;
    childClass.pafi = 1.0D;
    childClass.claimAmount = 2.0D;
    childClass.returnCount = 3.44D;
    childClass.accCount = new BigInteger("5");
    childClass.snCount = new BigInteger("52");
    return Response.ok(parentClass).build();
}

Here is the POJO:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ParentClass", propOrder = {
    "ChildClass"
})
public class ParentClass {
    @XmlElement(name = "ChildClass", required = true)
    protected ChildClass childClass;
}


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ChildClass")
public class ChildClass {
    @XmlElement(name = "pafi")
    protected Double pafi;
    @XmlElement(required = true)
    protected BigInteger accCount;
    @XmlElement(name = "claimAmount")
    protected double claimAmount;
    @XmlElement(name = "snCount", required = true)
    protected BigInteger snCount;
    @XmlElement(name = "returnCount")
    protected double returnCount;
}

Actual o/p:

{
"ChildClass": {
    "accCount": 5,
    "pafi": **1**,
    "claimAmount": **2**,
    "snCount": 52,
    "returnCount": 3.44
}} 

Expected o/p:

{
"ChildClass": {
    "accCount": 5,
    "pafi": **1.0**,
    "claimAmount": **2.0**,
    "snCount": 52,
    "returnCount": 3.44
}} 
2

There are 2 answers

0
mkrakhin On BEST ANSWER

Well, that's not how JAX-RS marshall your response, that's how JavaScript works. Try something like this in console:

var a = 2.0;
console.log(a);

You will see 2 as an output. Should be part of ECMA specification, but I cannot find exact place. If you want, you could use toFixed method of Number on client side to preserve this decimal point (but it will convert Number to String).

1
zbig On

What I'm doing in my project is to convert the POJO with Jackson explicitly

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(JsonMethod.FIELD, JsonAutoDetect.Visibility.ANY); // this line is obligatory if you don't have setters/getters
Response.ok(mapper.writeValueAsString(parentClass)).build();

This way I'm getting desired double values like 2.0 in the output.

Of course you will have to add additional dependency to your project, for example with maven:

    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.13</version>
    </dependency>

This way you will achieve desired result, however this is just aesthetic difference if your client is written in dynamically typed language like JavaScript.