Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

class A declares multiple JSON fields

Tags:

java

json

gson

i have a class A which has some private fields and the same class extends another class B which also has some private fields which are in class A.

public class A extends B {
    private BigDecimal netAmountTcy;
    private BigDecimal netAmountPcy;   
    private BigDecimal priceTo;  
    private String segment;

    private BigDecimal taxAmountTcy;
    private BigDecimal taxAmountPcy;   
    private BigDecimal tradeFeesTcy;
    private BigDecimal tradeFeesPcy;

// getter and setter for the above fields

}

and class B has got some private fiedls which are in class A

now when i try to create JSON string from above class A i get the following exception :

class com.hexgen.ro.request.A declares multiple JSON fields named netAmountPcy

How to fix this?

Since they are private fields there should not be any problem while creating json string i guess but i am not sure.

i create json string like the following :

Gson gson = new Gson();
 tempJSON = gson.toJson(obj);

here obj is the object of class A

like image 530
Java Questions Avatar asked May 10 '13 06:05

Java Questions


3 Answers

Since they are private fields there should not be any problem while creating json string

I don't think this statement is true, GSON looks up at the object's private fields when serializing, meaning all private fields of superclass are included, and when you have fields with same name it throws an error.

If there's any particular field you don't want to include you have to mark it with transient keyword, eg:

private transient BigDecimal tradeFeesPcy;
like image 143
gerrytan Avatar answered Oct 19 '22 04:10

gerrytan


This is a bit late, but I ran into this exact same problem as well. The only thing was that I wasn't able to modify the superclass as that code wasn't mine. The way that I resolved this was by creating an exclusion strategy that skipped any field that had a field of the same name present in a superclass. Here is my code for that class:

public class SuperclassExclusionStrategy implements ExclusionStrategy
{
    public boolean shouldSkipClass(Class<?> arg0)
    {
        return false;
    }

    public boolean shouldSkipField(FieldAttributes fieldAttributes)
    {
        String fieldName = fieldAttributes.getName();
        Class<?> theClass = fieldAttributes.getDeclaringClass();

        return isFieldInSuperclass(theClass, fieldName);            
    }

    private boolean isFieldInSuperclass(Class<?> subclass, String fieldName)
    {
        Class<?> superclass = subclass.getSuperclass();
        Field field;

        while(superclass != null)
        {   
            field = getField(superclass, fieldName);

            if(field != null)
                return true;

            superclass = superclass.getSuperclass();
        }

        return false;
    }

    private Field getField(Class<?> theClass, String fieldName)
    {
        try
        {
            return theClass.getDeclaredField(fieldName);
        }
        catch(Exception e)
        {
            return null;
        }
    }
}

I then set the Serialization and Deserialization exclusion strategies in the builder as follows:

    builder.addDeserializationExclusionStrategy(new SuperclassExclusionStrategy());
    builder.addSerializationExclusionStrategy(new SuperclassExclusionStrategy());

Hopefully this helps someone!

like image 73
Adrian Lee Avatar answered Oct 19 '22 04:10

Adrian Lee


The same error message also happens if you have different fields, but they have the same @SerializedName.

@SerializedName("date_created")
private Date DateCreated;
@SerializedName("date_created")
private Integer matchTime;

Doing copy/paste you can simply make such mistake. So, look into the the class and its ancestors and check for that.

  1. You cannot have two fields with the same name.
  2. You cannot have two fields with the same serialized name.
  3. Types are irrelevant for these rules.
like image 18
Gangnus Avatar answered Oct 19 '22 03:10

Gangnus