使用GSON构建JSON响应对象

时间:2015-09-16 14:25:18

标签: android gson

我一直在使用Gson解析我对对象的响应。比方说,我有一个像

这样的回复
"response": {
    "message": "Retrieved Successfully",
    "data": {
        "user": {
            "name": "Ken", "address": "NewYork", "phoneNumber":"00808493433"
         }
    }
}

我像这样创建我的课程

public class Gottenresponse {
private Response response;

public Response getResponse() {
    return response;
}

public void setResponse(Response response) {
    this.response = response;
}

public class Response {
    private String message;
    private Data data;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }
}

public class Data {

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

public class User {
    String name = "", address = "", phoneNumber = "";

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}
}

但是,如果我的回答是这样的话

"response": {
    "message": "Retrieved Successfully",
    "data": "{name: 'Ken', address: 'NewYork', phoneNumber:'00808493433'}"
}

Data是字符串格式,我想拆分响应并将其附加到Java POJO对象。

由于

3 个答案:

答案 0 :(得分:1)

如果您对服务器序列化的格式有任何发言权,您应该要求他们使用您提到的第一种格式。如果您遇到封装在字符串中的JSON,则可以使用自定义TypeAdapter来解包它。一种方法是使用TypeAdapterFactory,以便在创建时可以获取委托TypeAdapter。基本思想是通过读取字符串来解析User类,然后将其传递回gson以解析为字符串而不是字段。

public class UserTypeAdapterFactory implements TypeAdapterFactory {
  @Override
  public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
    if (typeToken.getType() != User.class) {
      return null;
    }
    return UserAdapter(gson.getDelegateAdapter(this, typeToken));
  }

  private <T> TypeAdapter<T> UserAdapter (final TypeAdapter<T> delegateAdapter) {
    return new TypeAdapter<T>() {

      @Override
      public void write(JsonWriter out, T value) throws IOException {
        // Hand off the delagate, hoepfully you don't need to serialize in this ugly format
        delegateAdapter.write(out, value);
      }

      @Override
      public T read(JsonReader in) throws IOException {
        // Make sure the element is a string
        if(!in.peek().equals(JsonToken.STRING)) {
          // Not what we were expecting, could throw a parse exception here, too
          return null;
        }
        // Read the string and pass to the delegate adapter
        final String userData = in.nextString();
        // Need to create a new Reader because the data in the string is not strict JSON, so
        // must create a lenient reader for the string
        JsonReader userIn = new JsonReader(new StringReader(userData));
        userIn.setLenient(true);
        return delegateAdapter.read(userIn);
      }
    };
  }
}

然后,您可以更新Response课程以使用新工厂,并可选择重命名 -

public class Response {
    private String message;
    @JsonAdapter(UserTypeAdapterFactory.class)
    @SerializedName("data")
    private User user;
    //...
}

您也可以使用JsonDeserializer,但首选TypeAdapter

答案 1 :(得分:-1)

如果它是您的服务器,那么您应该修改服务器响应

否则解决方法可能是制作另一个名为Data的Java类(Data应该与User相同,只是名称不同) 然后你可以制作新的Data pojo,然后将其转换为User

答案 2 :(得分:-1)

您可以创建一个通用类Response。 示例代码:

public class Response<T> {

    @SerializableName("message")
    private String message;

    @SerializableName("data")
    private T data; 

    public void setData(T data) {
        this.data = data;
    }

    public T getData() {
        return data;    
    }
}

由于您使用的是gson,因此可以为Response对象添加反序列化器。在该反序列化器中,您必须将该字符串转换为有效json字符串中的“data”键,并将其解析为该T参数类型。