7

I want to parse json data into java object using google-gson.

Here is an example of the data I want to parse:

  {"isBean":{"userName":"test","password":"password112"}}

IsBean.java

public interface IsBean extends Serializable,IsSerializable{

    long getId();

}

User.java

public class User implements IsBean,IsSerializable,Serializable {

    String userName;
    String password;

    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public long getId() {
        return 0;
    }


}

RequestObj.java

public class RequestObj implements IsBean, Serializable,IsSerializable{

    IsBean  isBean;
    @Override
    public long getId() {
        return 0;
    }
     public IsBean getIsBean() {
        return isBean;
    }
    public void setIsBean(IsBean isBean) {
        this.isBean = isBean;
    }
}

Test.java

public class Test {

    public static void main(String[] args) {
        Gson gson = new Gson();
        User user=new User();
        user.setPassword("password112");
        user.setUserName("test");
        RequestObj requestObj=new RequestObj();
        requestObj.setIsBean(user);
        String jsonStr=gson.toJson(requestObj);
        System.out.println("jsonStr--->"+jsonStr);
        try{
            RequestObj request=gson.fromJson(jsonStr, RequestObj.class);
        }catch (Exception e) {
        e.printStackTrace();
        }
    }
}

Error:

java.lang.RuntimeException: Unable to invoke no-args constructor for interface com.test.gson.shared.IsBean. Register an InstanceCreator with Gson for this type may fix this problem.
    at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:167)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:162)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
    at com.google.gson.Gson.fromJson(Gson.java:795)
    at com.google.gson.Gson.fromJson(Gson.java:761)
    at com.google.gson.Gson.fromJson(Gson.java:710)
    at com.google.gson.Gson.fromJson(Gson.java:682)
    at com.test.gson.server.Test.main(Test.java:18)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.google.gson.internal.UnsafeAllocator$1.newInstance(UnsafeAllocator.java:48)
    at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:164)
    ... 8 more
Caused by: java.lang.InstantiationException: com.test.gson.shared.IsBean
    at sun.misc.Unsafe.allocateInstance(Native Method)
    ... 14 more
bNd
  • 7,512
  • 7
  • 39
  • 72

2 Answers2

6

Without seeing the code of CommunicationObject, I can't say for sure BUT I am guessing with confidence that the class has a field of type IsBean in which you use it to hold the User. If so, the problem is that GSON scans fields of the object obj of the class CommunicationObject and based on the field definition, the value of the field (which is typed IsBean) will have to be created BUT since the type is an interface, it can't instance object for that field.

Another words, as JSON field does not specifies the object type, GSON must relies on the defined type of the field to create the instance for the field value which can't be done if the type is an interface.

So, consider changing the type of that field if that make sense to you. OR look into creating InstanceCreator of IsBean (doute that it is logically possible).

See also: Deserializing an abstract class in Gson

Hope this helps.

Community
  • 1
  • 1
NawaMan
  • 25,129
  • 10
  • 51
  • 77
  • As I suspected. Unfortunately interface (abstract class) field will be a default way to create its instance. So you have to decide what is the default type for `IsBean`. – NawaMan Dec 14 '12 at 06:58
1

The problem is solved With the help of Stackoverflow Answer.

Create gson object:

Gson gson = new GsonBuilder().registerTypeAdapter(IsBean.class, new InterfaceAdapter<IsBean>()).create();
Community
  • 1
  • 1
bNd
  • 7,512
  • 7
  • 39
  • 72