用动态键改造gson [英] Retrofit gson with dynamic keys
问题描述
我设法在没有动态键的情况下使其正常工作.通过遵循
这是响应格式:
{"dynamic1":{"cityID":"id1","priceRange":15},"dynamic2":{"cityID":"id2","priceRange":15}}
在APIUtils.java
公共静态CityService getCitiesService(){返回RetrofitClient.getClient(BASE_URL).create(CityService.class);}
在CityService.java
公共接口CityService {@GET("/SAGetStrollAwayCity")呼叫< CityResponse>getCities();@GET("/SAGetStrollAwayCity")呼叫< CityResponse>getCities(@Query("tagged")String标签);}
在CityResponse.java中:
公共类CityResponse {/* @ SerializedName("results")@ Expose *///这是正确的方法吗?私人地图< String,CityDetails>city = new HashMap<>();公共地图< String,CityDetails>getCity(){返回城市;}public void setCity(Map< String,CityDetails> elemDetails){this.city = elemDetails;}}
在CityDetails.java中
公共类CityDetails {@SerializedName("cityID")@暴露私有String cityID;@SerializedName("priceRange")@暴露私有Integer priceRange;公共字符串getCityID(){返回cityID;}公共无效setCityID(String cityID){this.cityID = cityID;}public Integer getPriceRange(){返回priceRange;}public void setPriceRange(Integer priceRange){this.priceRange = priceRange;}}
在HomeFragment.java中
public View onCreateView(@NonNull LayoutInflater充气机,@ Nullable ViewGroup容器,@ Nullable Bundle saveInstanceState){查看rootView = inflater.inflate(R.layout.fragment_home,null);//第二次api调用mServiceCity = ApiUtils.getCitiesService();loadCities();返回rootView;}公共无效loadCities(){mServiceCity.getCities().enqueue(new Callback< CityResponse>(){@Overridepublic void onResponse(Call< CityResponse>呼叫,Response< CityResponse>响应){//!!!为什么响应身体为空???if(response.isSuccessful()){//adapter.updateCities(response.body().getCity());Log.d("MainActivity",从API加载的帖子" + response.body().getCity());}别的 {int statusCode = response.code();//根据状态码处理请求错误}}@Override公共无效onFailure(Call< CityResponse>呼叫,Throwable t){//showErrorMessage();Log.d("MainActivity",从API加载错误");}});}
我个人将删除 CityResponse
模型,并仅使用 Map< String,CityDetails>
.
改装界面可以是:
公共接口CityService {@GET("/SAGetStrollAwayCity")呼叫< Map< String,CityDetails>>getCities();@GET("/SAGetStrollAwayCity")呼叫< Map< String,CityDetails>>getCities(@Query("tagged")String标签);}
在您的方案中,响应正文为空,因为 CityResponse
将映射到以下json:
{城市": {"dynamic1":{"cityID":"id1","priceRange":15},"dynamic2":{"cityID":"id2","priceRange":15}}}
但是,您没有名为 city
的根元素.json本身已经可以映射到java Map
.
希望这会有所帮助.
I've managed to get it to work without a dynamic key. By following this tutorial with this json:
Currently, I'm using Retrofit and trying to get a response with dynamic keys. However, the response body is always null:
This is the response format:
{
"dynamic1": {
"cityID": "id1",
"priceRange": 15
},
"dynamic2": {
"cityID": "id2",
"priceRange": 15
}
}
In APIUtils.java
public static CityService getCitiesService() {
return RetrofitClient.getClient(BASE_URL).create(CityService.class);
}
In CityService.java
public interface CityService {
@GET("/SAGetStrollAwayCity")
Call<CityResponse> getCities();
@GET("/SAGetStrollAwayCity")
Call<CityResponse> getCities(@Query("tagged") String tags);
}
In CityResponse.java:
public class CityResponse {
/*@SerializedName("results")
@Expose*/ // is this the correct way?
private Map<String, CityDetails> city = new HashMap<>();
public Map<String, CityDetails> getCity() {
return city;
}
public void setCity(Map<String, CityDetails> elemDetails) {
this.city = elemDetails;
}
}
In CityDetails.java
public class CityDetails {
@SerializedName("cityID")
@Expose
private String cityID;
@SerializedName("priceRange")
@Expose
private Integer priceRange;
public String getCityID() {
return cityID;
}
public void setCityID(String cityID) {
this.cityID = cityID;
}
public Integer getPriceRange() {
return priceRange;
}
public void setPriceRange(Integer priceRange) {
this.priceRange = priceRange;
}
}
In HomeFragment.java
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, null);
// 2nd api call
mServiceCity = ApiUtils.getCitiesService();
loadCities();
return rootView;
}
public void loadCities() {
mServiceCity.getCities().enqueue(new Callback<CityResponse>() {
@Override
public void onResponse(Call<CityResponse> call, Response<CityResponse> response) {
// !!! WHY IS THE RESPONSE BODY EMPTY???
if(response.isSuccessful()) {
// adapter.updateCities(response.body().getCity());
Log.d("MainActivity", "posts loaded from API"+ response.body().getCity());
}else {
int statusCode = response.code();
// handle request errors depending on status code
}
}
@Override
public void onFailure(Call<CityResponse> call, Throwable t) {
//showErrorMessage();
Log.d("MainActivity", "error loading from API");
}
});
}
Personally I'd drop the CityResponse
model and just work with Map<String, CityDetails>
.
The retrofit interface can then be:
public interface CityService {
@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities();
@GET("/SAGetStrollAwayCity")
Call<Map<String, CityDetails>> getCities(@Query("tagged") String tags);
}
In your scenario, the response body is empty because CityResponse
would map to a json like:
{
"city": {
"dynamic1": {
"cityID": "id1",
"priceRange": 15
},
"dynamic2": {
"cityID": "id2",
"priceRange": 15
}
}
}
However, you don't have a root element called city
. The json itself can already be mapped to a java Map
.
Hope this helps.
这篇关于用动态键改造gson的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!