使用嵌套请求参数改造 post 数据
Retrofit post data with nested request params
目前我正在改造。我知道 post 具有自定义对象的数据以及普通和多格式数据。但是我被卡住了,因为我想 post 使用嵌套请求参数将数据发送到服务器。
例如,
devicetype": "simulator",
"deviceid": "6ea09052e5b1fd10",
"appversion": "0.1",
"apiversion": "0.1",
我可以 post 作为 RequestBody
字符串,因为我想要 post 数据和使用多形式数据的图像。所以我已经清除了这个概念。
但现在我有另一个自定义数据。
"sitedetail": {
"id": "1",
"name": "xxx",
"visitorid": "1"
},
那么我如何将其作为请求参数传递。确实需要传递一个 @Body ,我们通常将其作为自定义数据或 json 数据传递。我卡在这里了。
更新
{
"devicetype": "simulator",
"deviceid": "6ea09052e5b1fd10",
"appversion": "0.1",
"apiversion": "0.1",
"timezone": "Asia/Kolkata",
"modeltype": "MI A1",
"deviceos": "9.0",
"userdeviceid": "1",
"visitorid": "1",
"siteid": "1",
"visitordetail": {
"id": "1",
"userid": "2",
"name": "xxx",
"email": "xxx@xxx.in",
"mobile": "xxxxxxxxx",
"dealername": "xxx"
},
"sitedetail": {
"id": "1",
"name": "xxx",
"visitorid": "1"
},
"selections": [
{
"id": "1",
"visitorid": "1",
"siteid": "1",
"designno": "xxx",
"qty": "3",
"roomtype": "xxx",
"remarks": "xxx"
},
{
"id": "0",
"visitorid": "1",
"siteid": "1",
"designno": "xxx",
"qty": "3",
"roomtype": "xxx",
"remarks": "xxx"
}
]}
高级帮助将不胜感激!
我认为您应该将 json 作为请求正文发送。为此,您需要 generate 相应 json 的 pojo。让我们称之为,ReqBody
然后,
// Add header items if required
@POST("endpoint")
Call<ResBody> getData(@Body ReqBody body);
此外,将 .addConverterFactory(GsonConverterFactory.create())
添加到您的 Retrofit.Builder()
。
我认为您遇到了我几天前遇到的同样问题。您可以在此处找到整个主题以查看我的示例:
你必须这样做:
public interface API {
@POST("YOUR_ENDPOINT")
Call<Post> createPost(@Body PostRequest post);
}
并创建这个 class:
public class PostRequest {
final Param1Type param1name;
final Param2Type param2name;
PostRequest(Param1Type param1name, Param2Type param2name) {
this.param1name= param1name;
this.param2name= param2name;
}
}
你可以试试这个,首先你需要为请求的第一部分创建一个 class。所以我会创建这样的东西 ->
class Article(
@field:Json(name = "devicetype") var devicetype: String,
@field:Json(name = "deviceid") var deviceid: String,
@field:Json(name = "appversion") var appversion: String,
@field:Json(name = "apiversion") var apiversion: String,
@field:Json(name = "timezone") var timezone: String,
@field:Json(name = "modeltype") var modeltype: String,
@field:Json(name = "deviceos") var deviceos: String,
@field:Json(name = "userdeviceid") var userdeviceid: String,
@field:Json(name = "visitorid") var visitorid: String,
@field:Json(name = "siteid") var siteid: String,
@field:Json(name = "visitordetail") var visitordetail: List<VisitorDetail> //Call the visitordetail class over here like this
) : Serializable
然后为 "visitordetail" 创建一个 class 文件,像这样 ->
class VisitorDetail(
@field:Json(name = "id") var id: String,
@field:Json(name = "userid") var userid: String,
@field:Json(name = "name") var name: String,
@field:Json(name = "email") var email: String,
@field:Json(name = "mobile") var mobile: String,
@field:Json(name = "dealername") var dealername: String,
@field:Json(name = "sitedetail") var sitedetail: List<SiteDetail> //Call the site details class over here like this
) : Serializable
然后类似地创建一个名为 "sitedetail"
的 class
class SiteDetail(
@field:Json(name = "id") var id: String,
@field:Json(name = "name") var name: String,
@field:Json(name = "visitorid") var visitorid: String,
@field:Json(name = "selections") var selections: List<Selections> //Call the Selections class over here
): Serializable
同样地再次做同样的事情,像这样为 "selections" 创建一个 class ->
class Selections(
@field:Json(name = "id") var id: String,
@field:Json(name = "visitorid") var visitorid: String,
@field:Json(name = "siteid") var siteid: String,
@field:Json(name = "designno") var designno: String,
@field:Json(name = "qty") var qty: String,
@field:Json(name = "roomtype") var roomtype: String,
@field:Json(name = "remarks") var remarks: String
):Serializable
我已经在 Kotlin 中完成了此操作,但您可以在 java 中通过转换来尝试。逻辑是,只要需要调用嵌套请求数据,您只需将所有响应转换为 pojo classes。只需将其一一传递,然后将主 pojo 调用到您的改造中,其余部分将由库处理。你也可以为多部分做这个。
如果有任何愚蠢的错误,比如缺少逗号之类的,那么我提前为此道歉。
我终于解决了这个问题。
如果有人想将带有额外附加参数的图像上传到服务器。方法如下
首先在改造 API 请求接口中创建方法。
@Multipart
@POST("test/test.post.json")
Call<APIResponseSiteDetails> addImages(@PartMap Map<String, RequestBody> params);
现在您必须在 activity 或片段 class 中您想调用的地方调用此方法。
Map<String, RequestBody> params = new HashMap<>();
if (imageData != null && imageData.size() > 0) {
for (int i = 0; i < imageData.size(); i++) {
String key = "images[" + i + "]";
File file = new File(imageData.get(i).getImageurl());
try {
File compressedImages = new ImageZipper(AddDetailsActivity.this).compressToFile(file);
params.put("" + key + "\"; filename=\"" + file.getName(), getRequestFile(compressedImages));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
以上代码片段仅用于使用 MultiPart 发送图像。现在,如果你想用它发送额外的参数。然后简单地使用这个。
params.put("devicetype", toRequestBody(Constants.DEVICE_TYPE)); // This is String request body.
现在,如果您有另一个使用密钥对值的自定义请求并且想要发送单个项目,那么您必须以这种方式打包。
public Map<String, RequestBody> getAnotherRequest() {
Map<String, RequestBody> paStringRequestBodyMap = new HashMap<>();
paStringRequestBodyMap.put("userid", Functions.toRequestBody("1"));
paStringRequestBodyMap.put("id", Functions.toRequestBody("1"));
return paStringRequestBodyMap;
}
现在你必须在主请求体中添加它然后你必须执行。
for (Map.Entry<String, RequestBody> entry : getAnotherRequest().entrySet()) {
String key = entry.getKey();
RequestBody value = entry.getValue();
params.put("details[" + key + "]", value);
}
现在,如果你想发送多个请求,那么你需要执行下面的代码,
public Map<String, Map> getContacts() {
Map<String, Map> paStringRequestBodyMap = new HashMap<>();
if (showRoomDataList != null && showRoomDataList.size() > 0) {
for (int i = 0; i < showRoomDataList.size(); i++) {
Map<String, RequestBody> innnerList = new HashMap<>();
innnerList.put("id", Functions.toRequestBody("0"));
innnerList.put("visitorid", Functions.toRequestBody("0"));
innnerList.put("siteid", Functions.toRequestBody("0"));
innnerList.put("typeid", Functions.toRequestBody(showRoomDataList.get(i).getTypeid()));
paStringRequestBodyMap.put(i + "", innnerList);
}
}
return paStringRequestBodyMap;
}
现在把它放到主要请求中,
for (Map.Entry<String, Map> entry : getContacts().entrySet()) {
String key = entry.getKey();
Map value = entry.getValue();
Iterator it = value.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
RequestBody requestBody = (RequestBody) pair.getValue();
params.put("contacts[" + key + "]" + "[" + pair.getKey() + "]", requestBody);
it.remove(); // avoids a ConcurrentModificationException
}
}
对于图像多部分请求正文
private RequestBody getRequestFile(File file) {
RequestBody fbody = RequestBody.create(MediaType.parse("image/*"), file);
return fbody;
}
对于字符串值请求正文
public static RequestBody toRequestBody(String value) {
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), value);
return body;
}
以上是使用带有图像(多部分)数据的密钥对值对单个、多个 post 请求执行的代码。我希望这对你们所有人都有帮助。
目前我正在改造。我知道 post 具有自定义对象的数据以及普通和多格式数据。但是我被卡住了,因为我想 post 使用嵌套请求参数将数据发送到服务器。
例如,
devicetype": "simulator",
"deviceid": "6ea09052e5b1fd10",
"appversion": "0.1",
"apiversion": "0.1",
我可以 post 作为 RequestBody
字符串,因为我想要 post 数据和使用多形式数据的图像。所以我已经清除了这个概念。
但现在我有另一个自定义数据。
"sitedetail": {
"id": "1",
"name": "xxx",
"visitorid": "1"
},
那么我如何将其作为请求参数传递。确实需要传递一个 @Body ,我们通常将其作为自定义数据或 json 数据传递。我卡在这里了。
更新
{
"devicetype": "simulator",
"deviceid": "6ea09052e5b1fd10",
"appversion": "0.1",
"apiversion": "0.1",
"timezone": "Asia/Kolkata",
"modeltype": "MI A1",
"deviceos": "9.0",
"userdeviceid": "1",
"visitorid": "1",
"siteid": "1",
"visitordetail": {
"id": "1",
"userid": "2",
"name": "xxx",
"email": "xxx@xxx.in",
"mobile": "xxxxxxxxx",
"dealername": "xxx"
},
"sitedetail": {
"id": "1",
"name": "xxx",
"visitorid": "1"
},
"selections": [
{
"id": "1",
"visitorid": "1",
"siteid": "1",
"designno": "xxx",
"qty": "3",
"roomtype": "xxx",
"remarks": "xxx"
},
{
"id": "0",
"visitorid": "1",
"siteid": "1",
"designno": "xxx",
"qty": "3",
"roomtype": "xxx",
"remarks": "xxx"
}
]}
高级帮助将不胜感激!
我认为您应该将 json 作为请求正文发送。为此,您需要 generate 相应 json 的 pojo。让我们称之为,ReqBody
然后,
// Add header items if required
@POST("endpoint")
Call<ResBody> getData(@Body ReqBody body);
此外,将 .addConverterFactory(GsonConverterFactory.create())
添加到您的 Retrofit.Builder()
。
我认为您遇到了我几天前遇到的同样问题。您可以在此处找到整个主题以查看我的示例:
你必须这样做:
public interface API {
@POST("YOUR_ENDPOINT")
Call<Post> createPost(@Body PostRequest post);
}
并创建这个 class:
public class PostRequest {
final Param1Type param1name;
final Param2Type param2name;
PostRequest(Param1Type param1name, Param2Type param2name) {
this.param1name= param1name;
this.param2name= param2name;
}
}
你可以试试这个,首先你需要为请求的第一部分创建一个 class。所以我会创建这样的东西 ->
class Article(
@field:Json(name = "devicetype") var devicetype: String,
@field:Json(name = "deviceid") var deviceid: String,
@field:Json(name = "appversion") var appversion: String,
@field:Json(name = "apiversion") var apiversion: String,
@field:Json(name = "timezone") var timezone: String,
@field:Json(name = "modeltype") var modeltype: String,
@field:Json(name = "deviceos") var deviceos: String,
@field:Json(name = "userdeviceid") var userdeviceid: String,
@field:Json(name = "visitorid") var visitorid: String,
@field:Json(name = "siteid") var siteid: String,
@field:Json(name = "visitordetail") var visitordetail: List<VisitorDetail> //Call the visitordetail class over here like this
) : Serializable
然后为 "visitordetail" 创建一个 class 文件,像这样 ->
class VisitorDetail(
@field:Json(name = "id") var id: String,
@field:Json(name = "userid") var userid: String,
@field:Json(name = "name") var name: String,
@field:Json(name = "email") var email: String,
@field:Json(name = "mobile") var mobile: String,
@field:Json(name = "dealername") var dealername: String,
@field:Json(name = "sitedetail") var sitedetail: List<SiteDetail> //Call the site details class over here like this
) : Serializable
然后类似地创建一个名为 "sitedetail"
的 classclass SiteDetail(
@field:Json(name = "id") var id: String,
@field:Json(name = "name") var name: String,
@field:Json(name = "visitorid") var visitorid: String,
@field:Json(name = "selections") var selections: List<Selections> //Call the Selections class over here
): Serializable
同样地再次做同样的事情,像这样为 "selections" 创建一个 class ->
class Selections(
@field:Json(name = "id") var id: String,
@field:Json(name = "visitorid") var visitorid: String,
@field:Json(name = "siteid") var siteid: String,
@field:Json(name = "designno") var designno: String,
@field:Json(name = "qty") var qty: String,
@field:Json(name = "roomtype") var roomtype: String,
@field:Json(name = "remarks") var remarks: String
):Serializable
我已经在 Kotlin 中完成了此操作,但您可以在 java 中通过转换来尝试。逻辑是,只要需要调用嵌套请求数据,您只需将所有响应转换为 pojo classes。只需将其一一传递,然后将主 pojo 调用到您的改造中,其余部分将由库处理。你也可以为多部分做这个。 如果有任何愚蠢的错误,比如缺少逗号之类的,那么我提前为此道歉。
我终于解决了这个问题。
如果有人想将带有额外附加参数的图像上传到服务器。方法如下
首先在改造 API 请求接口中创建方法。
@Multipart
@POST("test/test.post.json")
Call<APIResponseSiteDetails> addImages(@PartMap Map<String, RequestBody> params);
现在您必须在 activity 或片段 class 中您想调用的地方调用此方法。
Map<String, RequestBody> params = new HashMap<>();
if (imageData != null && imageData.size() > 0) {
for (int i = 0; i < imageData.size(); i++) {
String key = "images[" + i + "]";
File file = new File(imageData.get(i).getImageurl());
try {
File compressedImages = new ImageZipper(AddDetailsActivity.this).compressToFile(file);
params.put("" + key + "\"; filename=\"" + file.getName(), getRequestFile(compressedImages));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
以上代码片段仅用于使用 MultiPart 发送图像。现在,如果你想用它发送额外的参数。然后简单地使用这个。
params.put("devicetype", toRequestBody(Constants.DEVICE_TYPE)); // This is String request body.
现在,如果您有另一个使用密钥对值的自定义请求并且想要发送单个项目,那么您必须以这种方式打包。
public Map<String, RequestBody> getAnotherRequest() {
Map<String, RequestBody> paStringRequestBodyMap = new HashMap<>();
paStringRequestBodyMap.put("userid", Functions.toRequestBody("1"));
paStringRequestBodyMap.put("id", Functions.toRequestBody("1"));
return paStringRequestBodyMap;
}
现在你必须在主请求体中添加它然后你必须执行。
for (Map.Entry<String, RequestBody> entry : getAnotherRequest().entrySet()) {
String key = entry.getKey();
RequestBody value = entry.getValue();
params.put("details[" + key + "]", value);
}
现在,如果你想发送多个请求,那么你需要执行下面的代码,
public Map<String, Map> getContacts() {
Map<String, Map> paStringRequestBodyMap = new HashMap<>();
if (showRoomDataList != null && showRoomDataList.size() > 0) {
for (int i = 0; i < showRoomDataList.size(); i++) {
Map<String, RequestBody> innnerList = new HashMap<>();
innnerList.put("id", Functions.toRequestBody("0"));
innnerList.put("visitorid", Functions.toRequestBody("0"));
innnerList.put("siteid", Functions.toRequestBody("0"));
innnerList.put("typeid", Functions.toRequestBody(showRoomDataList.get(i).getTypeid()));
paStringRequestBodyMap.put(i + "", innnerList);
}
}
return paStringRequestBodyMap;
}
现在把它放到主要请求中,
for (Map.Entry<String, Map> entry : getContacts().entrySet()) {
String key = entry.getKey();
Map value = entry.getValue();
Iterator it = value.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
RequestBody requestBody = (RequestBody) pair.getValue();
params.put("contacts[" + key + "]" + "[" + pair.getKey() + "]", requestBody);
it.remove(); // avoids a ConcurrentModificationException
}
}
对于图像多部分请求正文
private RequestBody getRequestFile(File file) {
RequestBody fbody = RequestBody.create(MediaType.parse("image/*"), file);
return fbody;
}
对于字符串值请求正文
public static RequestBody toRequestBody(String value) {
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), value);
return body;
}
以上是使用带有图像(多部分)数据的密钥对值对单个、多个 post 请求执行的代码。我希望这对你们所有人都有帮助。