【问题标题】:Retrofit gson with dynamic keys用动态键改造 gson
【发布时间】:2019-04-17 04:33:19
【问题描述】:

我已经设法让它在没有动态密钥的情况下工作。关注这个tutorial 和这个json

目前,我正在使用 Retrofit 并尝试使用动态键获得响应。但是,响应正文始终为空:

这是响应格式:

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

在 APIUtils.java 中

    public static CityService getCitiesService() {
        return RetrofitClient.getClient(BASE_URL).create(CityService.class);
    }

在 CityService.java 中

public interface CityService {

    @GET("/SAGetStrollAwayCity")
    Call<CityResponse> getCities();

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

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

}

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

        }
    });
}

【问题讨论】:

  • 您期待的响应是什么?
  • 您好,回复如下:{ "dynamic1": { "cityID": "id1", "priceRange": 15 }, "dynamic2": { "cityID": "id2", "priceRange ": 15 } }
  • 好吧,你的意思是说这不来了,总是空着来吧?
  • 你的 CityResponse 模型是错误的,因为没有@SerializedName(),它怎么知道它需要从哪个键解析..!!
  • @Ümañgßürmån 在回复中用断点更新了问题

标签: android gson retrofit2


【解决方案1】:

就我个人而言,我会放弃 CityResponse 模型而只使用 Map&lt;String, CityDetails&gt;

那么改造界面可以是:

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

希望这会有所帮助。

【讨论】:

  • :D 没关系,不用担心!很高兴它有帮助!把啤酒买给比我更需要的人:D
猜你喜欢
  • 2018-08-03
  • 2018-04-13
  • 2018-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-28
相关资源
最近更新 更多