Reputation: 1037
I call a request network to my server, and server always response a format json look like this format below:
{
"error": 200,
"message": "Login Success",
"message_app": "abcxyz",
"data": {
"client_id": "1423423",
"client_secret": "64646456546"
}
}
Only jsonObject data is include different field for each kind of request. Example for a new response:
{
"error": 200,
"message": "Get product success",
"message_app": "vcxvxcv",
"data": {
"product_title": "Product A",
"product_desc": "This is a description for product A"
}
}
So I decide to make a general class call ServerResult include a field "Object" so that I can cast it to a specific object.
//ServerResult.class
public class ServerResult {
private int error;
private String message;
private String message_app;
private Object data;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessageApp() {
return message_app;
}
public void setMessageApp(String messageApp) {
this.message_app = messageApp;
}
public int getError() {
return error;
}
public void setError(int error) {
this.error = error;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getMessage_app() {
return message_app;
}
public void setMessage_app(String message_app) {
this.message_app = message_app;
}
}
//Client.java
public class Client {
private String client_id;
private String client_secret;
public String getClientId() {
return client_id;
}
public void setClientId(String client_id) {
this.client_id = client_id;
}
public String getClientSecret() {
return client_secret;
}
public void setClientSecret(String client_secret) {
this.client_secret = client_secret;
}
}
After request finished, I convert json to a ServerResult object by GSON:
@Override
public void onResponse(String response) {
Gson gson = new Gson();
ServerResult serverResult = gson.fromJson(response, ServerResult.class); //convert json String to ServerResult object
}
And then cast Data object to a Client object
Client client = (Client)serverResult.getData(); // problem here
Log error from GSON :
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to mypackagename.Client
Is it problem relate with GSON ?
Upvotes: 1
Views: 2564
Reputation: 10299
When gson
parse your json
data. There is no way that gson
will know that your data
field contain client data
or product data
,as you haven't specified any particular object. So gson
will convert that data field into map object.
You can try below approach.
Change your ServerResult
as below.
public class ServerResult {
private int error;
private String message;
private String message_app;
private Map<String, String> data;
}
Now create util method to get Client
data from Map
.
public static Client getClient(Map<String, String> data){
Client client = new Client();
client.setClientId(data.get("client_id"));
client.setClientSecret(data.get("client_secret"));
return client;
}
Now use it like..
@Override
public void onResponse(String response) {
Gson gson = new Gson();
ServerResult serverResult = gson.fromJson(response, ServerResult.class); //convert json String to ServerResult object
Client client = getClient(serverResult.getData());
}
similarly you can also get product data from same ServerResult
object. without creating different parser class.
Upvotes: 0
Reputation: 10611
What you can do is to declare the 'data' field to be of type com.google.gson.JsonObject and parse it manually by checking what content there is.
For example:
JsonObject data = serverResult.getData();
if (data.has("client_id")) {
//parse it as Client
} else {
//parse it as another type
}
Upvotes: 1
Reputation: 1487
Unfortunately, it cannot work that way.
As you wrote, your data
field may come with different contents (i.e. as different classes) depending on the request.
All Gson can see is your object data
field in ServerResult
.
How is Gson supposed to know which exact kind of object (e.g. your Client
class) 'hides' within the data object? Gson will not check all available classes from your code and just "try to cast it".
Upvotes: 1