2016-03-28 5 views
1

я называю сеть запроса на мой сервер, и сервер всегда Ответные формат JSON выглядеть этот формат ниже:Gson не может бросить объект

{ 

    "error": 200, 
    "message": "Login Success", 
    "message_app": "abcxyz", 
    "data": { 
    "client_id": "1423423", 
    "client_secret": "64646456546" 
    } 
} 

Только JSONObject данные это включает в себя различные поля для каждого вида запроса. Пример для нового ответа:

{ 

    "error": 200, 
    "message": "Get product success", 
    "message_app": "vcxvxcv", 
    "data": { 
    "product_title": "Product A", 
    "product_desc": "This is a description for product A" 
    } 
} 

Так что я решил сделать общий вызов класса ServerResult включает в поле «Объект», так что я могу привести его к конкретному объекту.

// 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; 
    } 
} 

После запроса завершения преобразовать JSON в объект ServerResult по GSON:

@Override  
    public void onResponse(String response) {    
    Gson gson = new Gson(); 
    ServerResult serverResult = gson.fromJson(response, ServerResult.class); //convert json String to ServerResult object 

    } 

И затем передать объект Data объекту клиента

Client client = (Client)serverResult.getData(); // problem here 

ошибка входа в GSON:

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap не может быть приведен к mypackagename.Client

ли проблема с RELATE GSON ?

+0

есть метод GetData() в ваших ServerResults? – Jois

+0

@Jois: Да, конечно. – CauCuKien

+0

Не могли бы вы высказать свой полный серверный результат? – Jois

ответ

0

Когда gson разобрать ваши json данные. Нет никакого способа, чтобы gson знал, что ваше поле data содержит client data или product data, так как вы не указали какой-либо конкретный объект. Таким образом, gson преобразует это поле данных в объект карты.

Вы можете попробовать ниже подход.

Измените ServerResult, как показано ниже.

public class ServerResult { 
    private int error; 
    private String message; 
    private String message_app; 
    private Map<String, String> data; 
} 

Теперь создадим метод Util, чтобы получить Client данные из 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; 
} 

Теперь использовать его как ..

@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()); 
} 

так же вы можете также получить данные о продукте с той же ServerResult объекта. без создания разного класса парсера.

+0

Это отличный способ. Спасибо. – CauCuKien

+0

@CauCuKien рад, что это вам поможет. –

1

К сожалению, он не может работать так. Как вы писали, ваше поле data может поставляться с различным содержимым (т. Е. Как разные классы) в зависимости от запроса.

Все, что может видеть Gson, это ваше поле object data в ServerResult. Как Gson должен знать, какой именно объект (например, ваш класс Client) «скрывается» внутри объекта данных? Gson не будет проверять все доступные классы из вашего кода и просто «попытаться применить его».

+0

Итак, можете ли вы предложить правильный путь? Должен ли я создавать много моделей для каждого ответа? – CauCuKien

+0

Вы можете смоделировать свое поле данных как JSONObject (но я этого не тестировал) Редактировать: dev.bmax тоже предположил :) –

1

Что вы можете сделать, так это объявить поле данных «типа» com.google.gson.JsonObject и проанализировать его вручную, проверив, какой контент есть.

Например:

JsonObject data = serverResult.getData(); 
if (data.has("client_id")) { 
    //parse it as Client 
} else { 
    //parse it as another type 
} 
+0

Вы работаете. благодаря – CauCuKien

Смежные вопросы