英文:
Android java: How to create POJO and convert it into acceptable JSON for Cloud Firestore REST API
问题
public interface PlaceholderApi {
@POST("{userId}/documents/{timestamp}")
Call<Transaction.Result> saveLocationToCloud(
@Path("userId") String userId,
@Path("timestamp") long timestamp,
@Body LocationData data
);
}
public class NetworkService {
private static NetworkService instance;
private static final String WEB_API_KEY = "zaSy..........VWI";
private static final String BASE_URL_CLOUD
= "https://firestore.googleapis.com/v1/projects/alocationtracker/databases/(default)/documents/";
private Retrofit retrofit;
private NetworkService() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder client = new OkHttpClient.Builder()
.addInterceptor(interceptor);
client.interceptors().add(chain -> {
Request request = chain.request();
HttpUrl url = request.url().newBuilder().addQueryParameter("key", WEB_API_KEY).build();
request = request.newBuilder().url(url).build();
return chain.proceed(request);
});
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL_CLOUD)
.addConverterFactory(GsonConverterFactory.create())
.client(client.build())
.build();
}
public static NetworkService getInstance() {
if (instance == null) {
instance = new NetworkService();
}
return instance;
}
public PlaceholderApi getJsonApi() {
return retrofit.create(PlaceholderApi.class);
}
}
public class LocationData {
@SerializedName("userId")
@Expose
private String userId;
@SerializedName("timestamp")
@Expose
private long timestamp;
@SerializedName("longitude")
@Expose
private ValueWrapper longitude;
@SerializedName("latitude")
@Expose
private ValueWrapper latitude;
public LocationData(String userId) {
this.userId = userId;
}
public LocationData(String userId, Location location) {
this.userId = userId;
this.timestamp = location.getTime();
this.latitude = new ValueWrapper(location.getLatitude(), "doubleValue");
this.longitude = new ValueWrapper(location.getLongitude(), "doubleValue");
}
}
public class ValueWrapper {
@SerializedName("doubleValue")
private Double doubleValue;
@SerializedName("stringValue")
private String stringValue;
@SerializedName("integerValue")
private Integer integerValue;
public ValueWrapper(Double value, String type) {
if ("doubleValue".equals(type)) {
this.doubleValue = value;
} else if ("stringValue".equals(type)) {
this.stringValue = String.valueOf(value);
} else if ("integerValue".equals(type)) {
this.integerValue = value.intValue();
}
}
}
英文:
I made preview test REST API query via postman
like this
https://firestore.googleapis.com/v1/projects/MY_PROJECT_ID/databases/(default)/documents/USER_ID_HASH/documents/112233445566
JSON body example:
{
"fields": {
"longitude": {
"doubleValue": 35.5635
},
"latitude": {
"doubleValue": 45.5366
}
}
}
And getting http response 200
, so going to implement this in code using retrofit2
.
The issue is that "doubleValue"
is something like field transformation according to value type, so it may be also "stringValue" or "integerValue"
for example. And question is how to create POJO
class for further converting in JSON
body like JSON body example above?
What do I have for now:
API
public interface PlaceholderApi {
@POST("{userId}/documents/{timestamp}")
Call<Transaction.Result> saveLocationToCloud(
@Path("userId") String userId,
@Path("timestamp") long timestamp,
@Body LocationData data
);
}
Network service
public class NetworkService {
private static NetworkService instance;
private static final String WEB_API_KEY = "zaSy..........VWI";
private static final String BASE_URL_CLOUD
= "https://firestore.googleapis.com/v1/projects/alocationtracker/databases/(default)/documents/";
private Retrofit retrofit;
private NetworkService() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder client = new OkHttpClient.Builder()
.addInterceptor(interceptor);
client.interceptors().add(chain -> {
Request request = chain.request();
HttpUrl url = request.url().newBuilder().addQueryParameter("key", WEB_API_KEY).build();
request = request.newBuilder().url(url).build();
return chain.proceed(request);
});
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL_CLOUD)
.addConverterFactory(GsonConverterFactory.create())
.client(client.build())
.build();
}
public static NetworkService getInstance() {
if (instance == null) {
instance = new NetworkService();
}
return instance;
}
public PlaceholderApi getJsonApi() {
return retrofit.create(PlaceholderApi.class);
}
}
POJO
public class LocationData {
@SerializedName("userId")
@Expose
private String userId;
@SerializedName("timestamp")
@Expose
private long timestamp;
@SerializedName("longitude")
@Expose
private double longitude;
@SerializedName("latitude")
@Expose
private double latitude;
public LocationData(String userId) {
this.userId = userId;
}
public LocationData(String userId, Location location) {
this.userId = userId;
this.timestamp = location.getTime();
this.latitude = location.getLatitude();
this.longitude = location.getLongitude();
}
}
JSON I got with this has incorrect format without value type like "doubleValue"
etc.
{"latitude":19.9802209,"longitude":16.1852646,"timestamp":1599830853181,"userId":"2DBtYfX1uxQszxNmod83"}
I assume POJO class is the only thing I need to change somehow. Or maybe I need to change retrofit.create(PlaceholderApi.class)
on something else?
Any suggestions, please.
Thanks.
答案1
得分: 1
如果您从API获得以下响应:
{
"fields": {
"longitude": {
"doubleValue": 35.5635
},
"latitude": {
"doubleValue": 45.5366
}
}
}
那么请将您的模型更改为类似以下内容:
public class PlacesResponseModel {
@SerializedName("fields")
@Expose
private Fields fields;
public Fields getFields() {
return fields;
}
public void setFields(Fields fields) {
this.fields = fields;
}
}
public class Fields {
@SerializedName("longitude")
@Expose
private Longitude longitude;
@SerializedName("latitude")
@Expose
private Latitude latitude;
public Longitude getLongitude() {
return longitude;
}
public void setLongitude(Longitude longitude) {
this.longitude = longitude;
}
public Latitude getLatitude() {
return latitude;
}
public void setLatitude(Latitude latitude) {
this.latitude = latitude;
}
}
public class Latitude {
@SerializedName("doubleValue")
@Expose
private Double doubleValue;
public Double getDoubleValue() {
return doubleValue;
}
public void setDoubleValue(Double doubleValue) {
this.doubleValue = doubleValue;
}
}
public class Longitude {
@SerializedName("doubleValue")
@Expose
private Double doubleValue;
public Double getDoubleValue() {
return doubleValue;
}
public void setDoubleValue(Double doubleValue) {
this.doubleValue = doubleValue;
}
}
然后将其添加到类似以下的Retrofit API回调中:
public interface PlaceholderApi {
@POST("{userId}/documents/{timestamp}")
Call<PlacesResponseModel> saveLocationToCloud(
@Path("userId") String userId,
@Path("timestamp") long timestamp,
@Body LocationData data
);
}
最后一步,现在调用它,您应该能够得到已映射的模型。
英文:
If you are getting below response from the API
{
"fields": {
"longitude": {
"doubleValue": 35.5635
},
"latitude": {
"doubleValue": 45.5366
}
}
}
then change your model to something like below.
public class PlacesResponseModel {
@SerializedName("fields")
@Expose
private Fields fields;
public Fields getFields() {
return fields;
}
public void setFields(Fields fields) {
this.fields = fields;
}
}
public class Fields {
@SerializedName("longitude")
@Expose
private Longitude longitude;
@SerializedName("latitude")
@Expose
private Latitude latitude;
public Longitude getLongitude() {
return longitude;
}
public void setLongitude(Longitude longitude) {
this.longitude = longitude;
}
public Latitude getLatitude() {
return latitude;
}
public void setLatitude(Latitude latitude) {
this.latitude = latitude;
}
}
public class Latitude {
@SerializedName("doubleValue")
@Expose
private Double doubleValue;
public Double getDoubleValue() {
return doubleValue;
}
public void setDoubleValue(Double doubleValue) {
this.doubleValue = doubleValue;
}
}
public class Longitude {
@SerializedName("doubleValue")
@Expose
private Double doubleValue;
public Double getDoubleValue() {
return doubleValue;
}
public void setDoubleValue(Double doubleValue) {
this.doubleValue = doubleValue;
}
}
and add it in the retrofit API callback like below.
public interface PlaceholderApi {
@POST("{userId}/documents/{timestamp}")
Call<PlacesResponseModel> saveLocationToCloud(
@Path("userId") String userId,
@Path("timestamp") long timestamp,
@Body LocationData data
);
}
last step call this now, you should get your models mapped
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论