Search code examples
androidretrofit2

%3F instead of question mark in my Retrofit URL


I'm trying to send a picture to a server. My URL contains some parameters about my phone:

api/v2/user/email_register%3F_height=1184&_target=android/2&_width=768 

and this is the working variant:

api/v2/user/email_register?_height=1184&_target=android/2&_width=768

(without irritation %3? code)

Also, I'm trying to pass my picture inside @Body:

@POST("/{url}")
Observable<UpdateUserInfoPayload> register(
        @Header("x-device-id") String deviceId,
        @Body RequestBody requestBody,
        @Path(value = "url", encoded = true) String  method
);

Creating it with 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();
}

That is why I'm unable to use for example:

@FieldMap Map<String, String> params

to pass my parameters there, because @FieldMap requires @FormUrlEncoded while I'm unable to make @Body request with @FormUrlEncoded.

1)How to remove %3F from my URL String? (outside retrofit everythin is fine!)

2)Is there any easy way to send a picture?

UPD: <-- 403 Forbidden https://api.example.com/api/v2/user/5984/validate_password when I use @Field annotation:

@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
);

Everything works when I use it like that:

@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
    );

I want either to remove %3F or learn how to use Field in POST request without getting FORBIDDEN


Solution

  • Retrofit won't let you put the query string in the path. Take a look at @QueryMap instead, which is designed for this.