如何改造 class
How to make Retrofit class
我正在尝试使用 retrofit
库向 Riot API 发出 api 请求
和一个示例请求 returns json 如下所示:
{"dyrus":{"id":5908,"name":"Dyrus","profileIconId":752,"summonerLevel":30,"revisionDate":1431126576000}}
注意对象 dyrus
有多个子属性,我想获取 ID 属性。我遇到的问题是我不想只查找 dyrus
的 ID,也不想查找其他玩家的 ID。当我查找其他玩家时,对象的名称会根据我查找的名称而变化。例如这里是另一个示例请求:
{"theoddone":{"id":60783,"name":"TheOddOne","profileIconId":752,"summonerLevel":30,"revisionDate":1431327360000}}
theoddone
现在是对象的名称。如何进行改造 class 以根据被搜索的人动态更改对象的名称。或者如何访问 ID 属性?我的 class 现在看起来像这样但不起作用:
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
);
}
我的activity的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,但没有正确地将其放入 class.
好的,我知道了。虽然花了我很长时间。
所以首先你必须像下面这样创建一个自定义的 TypeAdapterFactory class:
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();
重要的部分是 "dyrus",您可以将其替换为您要查找的名称。
接下来将 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 class 是正确的,只要变量保留其名称,您可以随意命名。为清楚起见,您可以调用 class UserPOJO,只需将 Summoner 的所有实例重命名为 UserPojo
希望对您有所帮助!
我正在尝试使用 retrofit 库向 Riot API 发出 api 请求 和一个示例请求 returns json 如下所示:
{"dyrus":{"id":5908,"name":"Dyrus","profileIconId":752,"summonerLevel":30,"revisionDate":1431126576000}}
注意对象 dyrus
有多个子属性,我想获取 ID 属性。我遇到的问题是我不想只查找 dyrus
的 ID,也不想查找其他玩家的 ID。当我查找其他玩家时,对象的名称会根据我查找的名称而变化。例如这里是另一个示例请求:
{"theoddone":{"id":60783,"name":"TheOddOne","profileIconId":752,"summonerLevel":30,"revisionDate":1431327360000}}
theoddone
现在是对象的名称。如何进行改造 class 以根据被搜索的人动态更改对象的名称。或者如何访问 ID 属性?我的 class 现在看起来像这样但不起作用:
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
);
}
我的activity的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,但没有正确地将其放入 class.
好的,我知道了。虽然花了我很长时间。
所以首先你必须像下面这样创建一个自定义的 TypeAdapterFactory class:
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();
重要的部分是 "dyrus",您可以将其替换为您要查找的名称。
接下来将 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 class 是正确的,只要变量保留其名称,您可以随意命名。为清楚起见,您可以调用 class UserPOJO,只需将 Summoner 的所有实例重命名为 UserPojo
希望对您有所帮助!