改造响应体给出空
Retrofit response body gives null
我正在尝试使用 API returns JSON,并且我正在使用 Retrofit 获取响应并解析它
API 像下面这样重新运行 JSON:
{
"total": 1244881,
"totalHits": 500,
"hits": [
{
"id": 5205518,
"pageURL": "https://pixabay.com/photos/landscape-sea-sky-clouds-sunset-5205518/",
"type": "photo",
"tags": "landscape, sea, sky",
"previewURL": "https://cdn.pixabay.com/photo/2020/05/22/14/04/landscape-5205518_150.jpg",
"webformatWidth": 640,
"webformatHeight": 427,
...
...
},
...
...
]
}
为了让 GSON 将这个 json 转换成一个对象,我创建了两个 classes :
第一个是:RquestModel.java
public class RequestModel {
@SerializedName("total")
private long total;
@SerializedName("totalHits")
private long totalHits;
@SerializedName("hits")
private List<Image> hits;
//Getters and setters down here...
}
json 中数组的第二个 class 是:
public class Image {
@SerializedName("id")
private long id;
@SerializedName("pageURL")
private String pageURL;
@SerializedName("type")
private String type;
@SerializedName("tags")
private String tags;
@SerializedName("previewURL")
private String previewURL;
@SerializedName("previewWidth")
private long previewWidth;
@SerializedName("previewHeight")
private long previewHeight;
@SerializedName("webformatURL")
private String webformatURL;
@SerializedName("webformatWidth")
private long webformatWidth;
@SerializedName("webformatHeight")
private long webformatHeight;
@SerializedName("largeImageURL")
private String largeImageURL;
@SerializedName("imageWidth")
private long imageWidth;
@SerializedName("imageHeight")
private long imageHeight;
@SerializedName("imageSize")
private long imageSize;
@SerializedName("views")
private long views;
@SerializedName("downloads")
private long downloads;
@SerializedName("favorites")
private long favorites;
@SerializedName("likes")
private long likes;
@SerializedName("comments")
private long comments;
@SerializedName("user_id")
private long userId;
@SerializedName("user")
private String user;
@SerializedName("userImageURL")
private String userImageURL;
//Getters and Setters down here .....
}
而 GSON 转换器使用的接口是这样的:
public interface ImageAPIService {
@GET(".")
public Call<RequestModel> getRequest();
}
并且当我尝试像这样使用来自回调的响应时:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ImageAPIService api = retrofit.create(ImageAPIService.class);
Call<RequestModel> request = api.getRequest();
request.enqueue(new Callback<RequestModel>() {
@Override
public void onResponse(Call<RequestModel> call, Response<RequestModel> response) {
mViewModel.setTxt(response.body().getTotal() + "");
}
@Override
public void onFailure(Call<RequestModel> call, Throwable t) {
}
});
给出类型异常:java.lang.NullPointerException
:
java.lang.NullPointerException: Attempt to invoke virtual method 'long com.mapps.pixabayclient.models.RequestModel.getTotal()' on a null object reference
我尝试调试它,一切正常,我不知道我错过了什么。如果有人能注意到这个错误,我将不胜感激。
提前感谢您的帮助。
问题出在 @GET
注释中,因为我将 api/? 键移到了 GET 注释的括号内 -> @GET("api/?key=xxxxxxx")
但现在的问题是我应该在每个 GET 或任何其他请求类型中传递密钥。
是否有系统地在每个请求中传递密钥的解决方法?
因此,您已经发现的问题是,在您的设置中,密钥正在从请求中删除。这是我使用您的设置发出请求时的响应。
Response{protocol=http/1.1, code=400, message=Bad Request, url=https://pixabay.com/api/}
但事实并非如此。根据 Jake Wharton 的 ,如果我们使用 @GET(".")
,那么整个 base_url 就变成了请求 url。出于某种原因,您的情况并非如此。 [也许如果我们使用一些拦截器记录请求 url 那么我们可以更好地理解发生了什么(无论是改造问题还是后端问题)]。
无论如何,一种解决方案是为每个请求传递 api 密钥,如下所示:
@GET(".")
public Call<RequestModel> getRequest(@Query("key") String key);
并像这样调用函数:
api.getRequest("my_api_key")
另一个解决方案是将 api 密钥硬编码到 @GET("api/?key=xxxxx")
中,就像您已经做的那样。
更好的解决办法是拦截请求,在url中添加api关键查询参数。使用此解决方案,您不必为每个函数调用传递 api 键。
我正在尝试使用 API returns JSON,并且我正在使用 Retrofit 获取响应并解析它
API 像下面这样重新运行 JSON:
{
"total": 1244881,
"totalHits": 500,
"hits": [
{
"id": 5205518,
"pageURL": "https://pixabay.com/photos/landscape-sea-sky-clouds-sunset-5205518/",
"type": "photo",
"tags": "landscape, sea, sky",
"previewURL": "https://cdn.pixabay.com/photo/2020/05/22/14/04/landscape-5205518_150.jpg",
"webformatWidth": 640,
"webformatHeight": 427,
...
...
},
...
...
]
}
为了让 GSON 将这个 json 转换成一个对象,我创建了两个 classes :
第一个是:RquestModel.java
public class RequestModel {
@SerializedName("total")
private long total;
@SerializedName("totalHits")
private long totalHits;
@SerializedName("hits")
private List<Image> hits;
//Getters and setters down here...
}
json 中数组的第二个 class 是:
public class Image {
@SerializedName("id")
private long id;
@SerializedName("pageURL")
private String pageURL;
@SerializedName("type")
private String type;
@SerializedName("tags")
private String tags;
@SerializedName("previewURL")
private String previewURL;
@SerializedName("previewWidth")
private long previewWidth;
@SerializedName("previewHeight")
private long previewHeight;
@SerializedName("webformatURL")
private String webformatURL;
@SerializedName("webformatWidth")
private long webformatWidth;
@SerializedName("webformatHeight")
private long webformatHeight;
@SerializedName("largeImageURL")
private String largeImageURL;
@SerializedName("imageWidth")
private long imageWidth;
@SerializedName("imageHeight")
private long imageHeight;
@SerializedName("imageSize")
private long imageSize;
@SerializedName("views")
private long views;
@SerializedName("downloads")
private long downloads;
@SerializedName("favorites")
private long favorites;
@SerializedName("likes")
private long likes;
@SerializedName("comments")
private long comments;
@SerializedName("user_id")
private long userId;
@SerializedName("user")
private String user;
@SerializedName("userImageURL")
private String userImageURL;
//Getters and Setters down here .....
}
而 GSON 转换器使用的接口是这样的:
public interface ImageAPIService {
@GET(".")
public Call<RequestModel> getRequest();
}
并且当我尝试像这样使用来自回调的响应时:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ImageAPIService api = retrofit.create(ImageAPIService.class);
Call<RequestModel> request = api.getRequest();
request.enqueue(new Callback<RequestModel>() {
@Override
public void onResponse(Call<RequestModel> call, Response<RequestModel> response) {
mViewModel.setTxt(response.body().getTotal() + "");
}
@Override
public void onFailure(Call<RequestModel> call, Throwable t) {
}
});
给出类型异常:java.lang.NullPointerException
:
java.lang.NullPointerException: Attempt to invoke virtual method 'long com.mapps.pixabayclient.models.RequestModel.getTotal()' on a null object reference
我尝试调试它,一切正常,我不知道我错过了什么。如果有人能注意到这个错误,我将不胜感激。
提前感谢您的帮助。
问题出在 @GET
注释中,因为我将 api/? 键移到了 GET 注释的括号内 -> @GET("api/?key=xxxxxxx")
但现在的问题是我应该在每个 GET 或任何其他请求类型中传递密钥。
是否有系统地在每个请求中传递密钥的解决方法?
因此,您已经发现的问题是,在您的设置中,密钥正在从请求中删除。这是我使用您的设置发出请求时的响应。
Response{protocol=http/1.1, code=400, message=Bad Request, url=https://pixabay.com/api/}
但事实并非如此。根据 Jake Wharton 的 @GET(".")
,那么整个 base_url 就变成了请求 url。出于某种原因,您的情况并非如此。 [也许如果我们使用一些拦截器记录请求 url 那么我们可以更好地理解发生了什么(无论是改造问题还是后端问题)]。
无论如何,一种解决方案是为每个请求传递 api 密钥,如下所示:
@GET(".")
public Call<RequestModel> getRequest(@Query("key") String key);
并像这样调用函数:
api.getRequest("my_api_key")
另一个解决方案是将 api 密钥硬编码到 @GET("api/?key=xxxxx")
中,就像您已经做的那样。
更好的解决办法是