2015-05-11 3 views
2

Я пытаюсь использовать retrofit библиотеку, чтобы сделать запросы API к Riot API и пример запроса возвращает JSON, который выглядит следующим образом:Как сделать дооснащения класс

{"dyrus":{"id":5908,"name":"Dyrus","profileIconId":752,"summonerLevel":30,"revisionDate":1431126576000}} 

Обратите внимание на объект dyrus имеет несколько суб свойства, и я хочу получить свойство id. Проблема, с которой я сталкиваюсь, - это не просто поиск идентификатора для dyrus, но и для других игроков. Когда я смотрю на других игроков, имя объекта меняется в зависимости от имени, которое я ищу. Например вот другой пример запроса:

{"theoddone":{"id":60783,"name":"TheOddOne","profileIconId":752,"summonerLevel":30,"revisionDate":1431327360000}} 

theoddone теперь имя объекта. Как создать класс переопределения, который динамически изменяет имя объекта в зависимости от человека, которого ищут. Или как мне получить доступ к свойству id? Мой класс выглядит это прямо сейчас, но не работает:

public class Summoner { 

    private int id; 
    private String name; 
    private int profileIconId; 
    private int summonerLevel; 
    private int revisionDate; 

    /** 
    * 
    * @return 
    * The id 
    */ 
    public int getId() { 
     return id; 
    } 

    /** 
    * 
    * @param id 
    * The id 
    */ 
    public void setId(int id) { 
     this.id = id; 
    } 

    /** 
    * 
    * @return 
    * The name 
    */ 
    public String getName() { 
     return name; 
    } 

    /** 
    * 
    * @param name 
    * The name 
    */ 
    public void setName(String name) { 
     this.name = name; 
    } 

    /** 
    * 
    * @return 
    * The profileIconId 
    */ 
    public int getProfileIconId() { 
     return profileIconId; 
    } 

    /** 
    * 
    * @param profileIconId 
    * The profileIconId 
    */ 
    public void setProfileIconId(int profileIconId) { 
     this.profileIconId = profileIconId; 
    } 

    /** 
    * 
    * @return 
    * The summonerLevel 
    */ 
    public int getSummonerLevel() { 
     return summonerLevel; 
    } 

    /** 
    * 
    * @param summonerLevel 
    * The summonerLevel 
    */ 
    public void setSummonerLevel(int summonerLevel) { 
     this.summonerLevel = summonerLevel; 
    } 

    /** 
    * 
    * @return 
    * The revisionDate 
    */ 
    public int getRevisionDate() { 
     return revisionDate; 
    } 

    /** 
    * 
    * @param revisionDate 
    * The revisionDate 
    */ 
    public void setRevisionDate(int revisionDate) { 
     this.revisionDate = revisionDate; 
    } 
} 

Позволь мне знать, если вы хотите увидеть какую-либо другую часть, как я использую переоснащение. Заранее спасибо.

Интерфейс:

public interface SummonerId { 

    @GET("/api/lol/{region}/v1.4/summoner/by-name/{summonerName}") 
    void summoner(
     @Path("region") String region, 
     @Path("summonerName") String summonerName, 
     @Query("api_key") String apiKey, 
     Callback<Summoner> cb 
    ); 

} 

код в OnCreate метод моей деятельности:

RestAdapter restAdapter = new RestAdapter.Builder() 
      .setLogLevel(RestAdapter.LogLevel.FULL) 
      .setEndpoint("https://na.api.pvp.net") 
      .build(); 

SummonerId service = restAdapter.create(SummonerId.class); 

service.summoner("na", "dyrus", "MY API KEY", new Callback<Summoner>() { 
    @Override 
    public void success(Summoner summoner, Response response) { 
     //summoner.getId() == null 
    } 

    @Override 
    public void failure(RetrofitError error) { 

    } 
}); 

Когда я запускаю код успешно соединяется с сервером и получает право JSON, но не правильно поместите его в класс.

+0

Похоже, вы не получаете «Summoner», а что-то вроде «SommonerWrapper» с переменной типа «Summoner», названной в соответствии с summoner. Это имя переменной похоже на большую икоту. Вам понадобится пользовательский TypeAdapter от Gson. –

ответ

2

Хорошо, я понял. Тем не менее, я занял много времени.

Итак, сначала вы должны создать пользовательский TypeAdapterFactory как следующий класс:

public class ItemTypeAdapterFactory implements TypeAdapterFactory { 

    String name; 

    public ItemTypeAdapterFactory(String name) { 
     this.name = name; 
    } 

    public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) { 

     final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); 
     final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class); 

     return new TypeAdapter<T>() { 

      public void write(JsonWriter out, T value) throws IOException { 
       delegate.write(out, value); 
      } 

      public T read(JsonReader in) throws IOException { 

       JsonElement jsonElement = elementAdapter.read(in); 
       if (jsonElement.isJsonObject()) { 
        JsonObject jsonObject = jsonElement.getAsJsonObject(); 
        if (jsonObject.has(name) && jsonObject.get(name).isJsonObject()) 
        { 
         jsonElement = jsonObject.get(name); 
        } 
       } 

       return delegate.fromJsonTree(jsonElement); 
      } 
     }.nullSafe(); 
    } 
} 

Для вашего использования вы можете просто скопировать и вставить это, но, пожалуйста, попытаться понять, что происходит.

Далее вы должны реализовать пользовательский GsonBuilder нравится следующим образом:

Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ItemTypeAdapterFactory("dyrus")).create(); 

Важной частью является «Маркус Хилл», который вы можете заменить имя, которое вы ищете.

Затем добавьте gsonbuilder к вашему restadapter:

RestAdapter restAdapter = new RestAdapter.Builder() 
        .setEndpoint("your endpoint") 
        .setConverter(new GsonConverter(gson)) 
        .build(); 

Используйте следующий метод в интерфейсе подключения:

public void getCurrentUser(Callback<Summoner> response); 

и получить ответ POJO следующим образом:

ConnectionInterface connectionInterface = restAdapter.create(**ConnectionInterface.class**); 
    connectionInterface.getCurrentUser(new Callback<Summoner>() { 
     @Override 
     public void success(Summoner response, Response response2) { 
     } 

     @Override 
     public void failure(RetrofitError error) { 
      Log.e("Response", error.getLocalizedMessage().toString()); 
     } 
    }); 
} 

};

Ваш класс POJO правильный, вы можете называть его чем угодно, если переменные сохраняют свои имена.Вы можете вызвать класс UserPOJO для ясности и просто переименовать все экземпляры Summoner в UserPojo

Надеюсь, это поможет!

+0

Получил его на работу, спасибо. Один вопрос. Нужно ли мне создавать новый «RestAdapter» для каждого запроса? Если нет, то как сделать другой запрос с использованием одного и того же адаптера. Спасибо – benawad

+0

mmm, вы можете получить строку поиска извне в AdapterFactory, но дальше, чем я понятия не имею. – Smashing

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