%3F 而不是我的 Retrofit 中的问号 URL
%3F instead of question mark in my Retrofit URL
我正在尝试将图片发送到服务器。我的 URL 包含一些关于我的 phone:
的参数
api/v2/user/email_register%3F_height=1184&_target=android/2&_width=768
这是工作变体:
api/v2/user/email_register?_height=1184&_target=android/2&_width=768
(无刺激 %3?代码)
此外,我正在尝试在@Body 中传递我的照片:
@POST("/{url}")
Observable<UpdateUserInfoPayload> register(
@Header("x-device-id") String deviceId,
@Body RequestBody requestBody,
@Path(value = "url", encoded = true) String method
);
使用 MultipartBuilder 创建它:
protected RequestBody buildAvatar(String avatarPath) {
MultipartBuilder builder = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart(ParkApiUrl.PARAM_USER_NAME, name.getText().toString())
.addFormDataPart(ParkApiUrl.PARAM_USER_SECOND_NAME, lastName.getText().toString())
.addFormDataPart(ParkApiUrl.PARAM_EMAIL, email.getText().toString())
.addFormDataPart(ParkApiUrl.PARAM_USER_ENCODED_PASSWORD,
PasswordUtils.encodePassword(encodePassword()))
.addFormDataPart(ParkApiUrl.PARAM_USER_GENDER,
male.isChecked() ? EmailProfile.GENDER_MALE : EmailProfile.GENDER_FEMALE)
.addFormDataPart(ParkApiUrl.PARAM_PARSE_ID,
ParseInstallation.getCurrentInstallation().getObjectId());
File file = new File(avatarPath);;
int size = (int) file.length();
byte[] bytes = new byte[size];
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
buf.read(bytes, 0, bytes.length);
buf.close();
builder.addFormDataPart("photo", "image.jpg", RequestBody.create(MEDIA_TYPE_JPG, bytes));
} catch (IOException e) {
e.printStackTrace();
}
return builder.build();
}
这就是我无法使用的原因,例如:
@FieldMap Map<String, String> params
在那里传递我的参数,因为@FieldMap 需要@FormUrlEncoded 而我无法使用@FormUrlEncoded 发出@Body 请求。
1)如何从我的 URL 字符串中删除 %3F? (外部改造一切正常!)
2)有什么简单的方法可以发图片吗?
更新:
<-- 403 禁止 https://api.example.com/api/v2/user/5984/validate_password
当我使用 @Field 注释时:
@FormUrlEncoded
@POST("/{url}")
Observable<BooleanResponse> validatePassword(
@Header("x-device-id") String deviceId,
@Field(ParkApiUrl.PARAM_USER_ENCODED_PASSWORD) String password,
@Field(ParkApiUrl.PARAM_HEIGHT) String height,
@Field(ParkApiUrl.PARAM_WIDTH) String width,
@Field(ParkApiUrl.PARAM_TARGET) String target,
@Path(value = "url", encoded = true) String method
);
当我这样使用它时一切正常:
@FormUrlEncoded
@POST("/api/v2/user/5984/validate_password?_height=1184&_target=android%2F2&_width=768&_user_id=5984") //full url
Observable<BooleanResponse> validatePassword(
@Header("x-device-id") String deviceId,
@Field(ParkApiUrl.PARAM_USER_ENCODED_PASSWORD) String password
);
我想删除 %3F 或学习如何在 POST 请求中使用 Field 而不会收到 FORBIDDEN
Retrofit 不允许您将查询字符串放在路径中。请看一下 @QueryMap,这是专门为此设计的。
更好的想法是,发送图片的多部分请求
@Multipart
@POST("api/v2/user/email_register")
Observable<UpdateUserInfoPayload> register(@Part("_height") String height, @Part("_target") String target, @Part("_width") String width, @Part("imageFile") TypedFile file);
参考:https://futurestud.io/blog/retrofit-how-to-upload-files#introduction
无需 add/remove %3F 在改造中它会自动处理
作为参考:https://square.github.io/retrofit/2.x/retrofit/index.html?retrofit2/http/QueryMap.html
我使用 @QueryMap
和 ImmutableMap
。
在我的例子中,API 是:/api/static_pages/?q=A+B+C
我的解决方案:
第 1 步:
@GET("/api/static_pages")
Call<String> getStaticPagesByType(@HeaderMap HashMap<String, Object> header,
@QueryMap(encoded=true) Map<String, String> filters);
第 2 步:当我想调用 API:
List<String> listTypes = new ArrayList<>();
listTypes.add("A");
listTypes.add("B");
listTypes.add("C");
StringBuilder typeString = new StringBuilder();
int listSize = listType.size();
for (int i = 0; i < listSize - 1; i++) {
typeString.append(listType.get(i));
if(i != listSize-2){
typeString.append("+");
}
}
// The key is here!
ImmutableMap<String, String> types = ImmutableMap.of("q", typeString.toString());
getRetrofitClient().getStaticPagesByType(yourHeader, types)
希望对你的工作有所帮助。
编码愉快。
如果您需要传递包含路径和查询参数的动态 URL 字符串,您应该使用 @Url
Retrofit @Url
@POST(
Observable<UpdateUserInfoPayload> register(
@Header("x-device-id") String deviceId,
@Body RequestBody requestBody,
@Url String method
);
其中 method = api/v2/user/email_register?_height=1184&_target=android/2&_width=768
然后,请求将如下所示:
https://api.example.com/api/v2/user/email_register?_height=1184&_target=android/2&_width=768
你可以通过@QueryName
实现
它允许您在 Url 的末尾附加 ?
符号,然后在“?”之后附加您想要的字符串。符号
如果您的字符串已经编码,您可能还需要查看 @QueryName(encoded = true)
。
我正在尝试将图片发送到服务器。我的 URL 包含一些关于我的 phone:
的参数api/v2/user/email_register%3F_height=1184&_target=android/2&_width=768
这是工作变体:
api/v2/user/email_register?_height=1184&_target=android/2&_width=768
(无刺激 %3?代码)
此外,我正在尝试在@Body 中传递我的照片:
@POST("/{url}")
Observable<UpdateUserInfoPayload> register(
@Header("x-device-id") String deviceId,
@Body RequestBody requestBody,
@Path(value = "url", encoded = true) String method
);
使用 MultipartBuilder 创建它:
protected RequestBody buildAvatar(String avatarPath) {
MultipartBuilder builder = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart(ParkApiUrl.PARAM_USER_NAME, name.getText().toString())
.addFormDataPart(ParkApiUrl.PARAM_USER_SECOND_NAME, lastName.getText().toString())
.addFormDataPart(ParkApiUrl.PARAM_EMAIL, email.getText().toString())
.addFormDataPart(ParkApiUrl.PARAM_USER_ENCODED_PASSWORD,
PasswordUtils.encodePassword(encodePassword()))
.addFormDataPart(ParkApiUrl.PARAM_USER_GENDER,
male.isChecked() ? EmailProfile.GENDER_MALE : EmailProfile.GENDER_FEMALE)
.addFormDataPart(ParkApiUrl.PARAM_PARSE_ID,
ParseInstallation.getCurrentInstallation().getObjectId());
File file = new File(avatarPath);;
int size = (int) file.length();
byte[] bytes = new byte[size];
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
buf.read(bytes, 0, bytes.length);
buf.close();
builder.addFormDataPart("photo", "image.jpg", RequestBody.create(MEDIA_TYPE_JPG, bytes));
} catch (IOException e) {
e.printStackTrace();
}
return builder.build();
}
这就是我无法使用的原因,例如:
@FieldMap Map<String, String> params
在那里传递我的参数,因为@FieldMap 需要@FormUrlEncoded 而我无法使用@FormUrlEncoded 发出@Body 请求。
1)如何从我的 URL 字符串中删除 %3F? (外部改造一切正常!)
2)有什么简单的方法可以发图片吗?
更新: <-- 403 禁止 https://api.example.com/api/v2/user/5984/validate_password 当我使用 @Field 注释时:
@FormUrlEncoded
@POST("/{url}")
Observable<BooleanResponse> validatePassword(
@Header("x-device-id") String deviceId,
@Field(ParkApiUrl.PARAM_USER_ENCODED_PASSWORD) String password,
@Field(ParkApiUrl.PARAM_HEIGHT) String height,
@Field(ParkApiUrl.PARAM_WIDTH) String width,
@Field(ParkApiUrl.PARAM_TARGET) String target,
@Path(value = "url", encoded = true) String method
);
当我这样使用它时一切正常:
@FormUrlEncoded
@POST("/api/v2/user/5984/validate_password?_height=1184&_target=android%2F2&_width=768&_user_id=5984") //full url
Observable<BooleanResponse> validatePassword(
@Header("x-device-id") String deviceId,
@Field(ParkApiUrl.PARAM_USER_ENCODED_PASSWORD) String password
);
我想删除 %3F 或学习如何在 POST 请求中使用 Field 而不会收到 FORBIDDEN
Retrofit 不允许您将查询字符串放在路径中。请看一下 @QueryMap,这是专门为此设计的。
更好的想法是,发送图片的多部分请求
@Multipart
@POST("api/v2/user/email_register")
Observable<UpdateUserInfoPayload> register(@Part("_height") String height, @Part("_target") String target, @Part("_width") String width, @Part("imageFile") TypedFile file);
参考:https://futurestud.io/blog/retrofit-how-to-upload-files#introduction
无需 add/remove %3F 在改造中它会自动处理
作为参考:https://square.github.io/retrofit/2.x/retrofit/index.html?retrofit2/http/QueryMap.html
我使用 @QueryMap
和 ImmutableMap
。
在我的例子中,API 是:/api/static_pages/?q=A+B+C
我的解决方案:
第 1 步:
@GET("/api/static_pages")
Call<String> getStaticPagesByType(@HeaderMap HashMap<String, Object> header,
@QueryMap(encoded=true) Map<String, String> filters);
第 2 步:当我想调用 API:
List<String> listTypes = new ArrayList<>();
listTypes.add("A");
listTypes.add("B");
listTypes.add("C");
StringBuilder typeString = new StringBuilder();
int listSize = listType.size();
for (int i = 0; i < listSize - 1; i++) {
typeString.append(listType.get(i));
if(i != listSize-2){
typeString.append("+");
}
}
// The key is here!
ImmutableMap<String, String> types = ImmutableMap.of("q", typeString.toString());
getRetrofitClient().getStaticPagesByType(yourHeader, types)
希望对你的工作有所帮助。
编码愉快。
如果您需要传递包含路径和查询参数的动态 URL 字符串,您应该使用 @Url
Retrofit @Url
@POST(
Observable<UpdateUserInfoPayload> register(
@Header("x-device-id") String deviceId,
@Body RequestBody requestBody,
@Url String method
);
其中 method = api/v2/user/email_register?_height=1184&_target=android/2&_width=768
然后,请求将如下所示:
https://api.example.com/api/v2/user/email_register?_height=1184&_target=android/2&_width=768
你可以通过@QueryName
实现
它允许您在 Url 的末尾附加 ?
符号,然后在“?”之后附加您想要的字符串。符号
如果您的字符串已经编码,您可能还需要查看 @QueryName(encoded = true)
。