Дооснащение GSON динамическими клавишами - PullRequest
0 голосов
/ 14 ноября 2018

Мне удалось заставить его работать без динамического ключа. Следуя этому учебнику с этим json :

В настоящее время я использую Retrofit и пытаюсь получить ответ с помощью динамических клавиш. Однако тело ответа всегда равно нулю:

enter image description here

Это формат ответа:

{
    "dynamic1": {
        "cityID": "id1",
        "priceRange": 15
    },
    "dynamic2": {
        "cityID": "id2",
        "priceRange": 15
    }
}

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

}

В 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");

        }
    });
}

1 Ответ

0 голосов
/ 14 ноября 2018

Лично я бы отбросил модель CityResponse и просто работал бы с Map<String, CityDetails>.

Интерфейс модернизации может быть таким:

public interface CityService {

  @GET("/SAGetStrollAwayCity")
  Call<Map<String, CityDetails>> getCities();

  @GET("/SAGetStrollAwayCity")
  Call<Map<String, CityDetails>> getCities(@Query("tagged") String tags);
}

В вашем сценарии тело ответапусто, потому что CityResponse будет отображаться в json, как:

{
  "city": {
    "dynamic1": {
      "cityID": "id1",
      "priceRange": 15
    },
    "dynamic2": {
      "cityID": "id2",
      "priceRange": 15
    }
  }
}

Однако у вас нет корневого элемента с именем city.Сам json уже может быть сопоставлен с java Map.

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

...