Retrofit & Gson - prevent gson from converting Long to scientific notation

Viewed 1435

Summary

I've been using Retrofit and Gson in my android app for a while but the IDs I get from the server are 13 digit numbers. Gson automatically converts those numbers to scientific notation, then casts it to String/Long, whatever I specify.

Here is a sample Retrofit class with an ID

public class User implements Serializable {

    @SerializedName("accessToken")
    @Expose
    public String accessToken;

    @SerializedName("userId")
    @Expose
    public String userId; //This is where it casts it into a Scientific notation

    @SerializedName("userRole")
    @Expose
    public int userRole;

    @SerializedName("name")
    @Expose
    public String name;

    @SerializedName("mobile")
    @Expose
    public String mobile;

    @SerializedName("countryId")
    @Expose
    public String countryId; //Here too

    @SerializedName("email")
    @Expose
    public String email;

    @SerializedName("username")
    @Expose
    public String username;


}

This is the Screenshot I got from the debugger

User implements Serializable Response

Solutions I've tried

This doesn't work for some reason

How to prevent Gson from converting a long number (a json string ) to scientific notation format?

As I've checked the debugger, my control flow never goes into serialize(Double src, Type typeOfSrc, JsonSerializationContext context)

switch off scientific notation in Gson double serialization

    @Override
    public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
        if(src == src.longValue())
            return new JsonPrimitive(src.longValue());          
        return new JsonPrimitive(src);
    }

Another solution I've tried

How to prevent Gson from expressing integers as floats

And this is my current RetrofitBuilder Method

        Retrofit.Builder rBuilder = new Builder();
        rBuilder.baseUrl(API_URL);
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(Double.class,  new JsonSerializer<Double>() {
                @Override
                public JsonElement serialize(final Double src, final Type typeOfSrc, final JsonSerializationContext context) {
                    BigDecimal value = BigDecimal.valueOf(src);
                    return new JsonPrimitive(value);
                }
            });
        gsonBuilder.registerTypeAdapter(Long.class,  new JsonSerializer<Long>() {
                @Override
                public JsonElement serialize(final Long src, final Type typeOfSrc, final JsonSerializationContext context) {
                    BigDecimal value = BigDecimal.valueOf(src);
                    return new JsonPrimitive(value);
                }
            });

        rBuilder.addConverterFactory(GsonConverterFactory.create(gsonBuilder.create()));

Any kind of help anywhere would be highly appreciated.

1 Answers

Just in case someone might run into the same problem,

I was using a Wrapper-Class for the response, of which the Data Type was specified was Object. For this, Gson was trying to convert it to Scientific notation no matter what.

I must actually use JsonElement from Gson

public class GenericResponse_ implements Serializable {

    @SerializedName("status")
    @Expose
    public int status;

    @SerializedName("error")
    @Expose
    public String error;

    @SerializedName("data")
    @Expose
    public JsonElement data; //This was of type Object, changed to JsonElement
}
Related