In my setup, I get all the paths for my resources from the REST API from an initial call to the API. We use this pattern to be able to change all the resource paths without breaking all existing app versions in the process.
I have been playing around with Retrofit and I tried to create a method that would accept any path I pass to it as a string. My try looks like this
@GET("/{path}")
public FooBar getFooBar(@Path("path") String path);
I then try to call it as follows.
String path = "foo/bar";
api.getFooBar(path);
Unfortunately Retrofit URL-Encodes the path replacement and I end up making a request to /foo%2Fbar
instead of /foo/bar
. Is there any way to disable URL-Encoding for path replacements or to make replacements spanning multiple path segments? Unfortunately I don't even know how many path segments there are, it is all controlled by the API.
Use @EncodedPath
! That's it. I'll copy the Javadoc so this answer has more meat:
Named replacement in the URL path. Values are converted to string using
String.valueOf(Object)
. Values are used literally without URL encoding. See@Path
for URL encoding equivalent.
Use it like this:
@GET("/{path}") void example(@EncodedPath("path") String path, ..);
Since @EncodedPath is deprecated now
Retrofit 1.9:
@GET("/{path}")
void example(@Path(value = "path", encoded = false) String path, ..);
Retrofit 2.*:
@GET("/{path}")
void example(@Path(value = "path", encoded = false) String path, ..);
There are known bugs, and you can watch the bugreport on: Retrofit @Github
There is also a link to possible solutions: Solution @Github
In the end, the message from the retrofit developers is:
"Path replacements that span multiple path segments aren't going to be supported, you should use @Url to build the full relative URL programmatically if the number of path segments varies dynamically."
So if you are in trouble with encode, the solution can be:
Your API for GET:
@GET
Call<Object> Function(@Url String path, @Query("CONTENT") String content);
Your API for POST:
@FormUrlEncoded
@POST
Call<Object> Function(@Url String path, @Field("CONTENT") String content);
And you can call it with this:
String thePath = "www.foo.de/foo/foo2";
Call<Object> call = api.Function(thePath,content);
So with this you dont have the problem to encode something.
But if you are just looking for the normal encode in version 2.* the API has to be like this:
@GET("/{path}")
void example(@Path(value = "path", encoded = false) String path, ..);
Regards
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With