Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit and Slash characters in PATH

I am facing an issue with Retrofit and would like to find a suitable answer as the only way I can think of it is pretty ugly and not practical.

Retrofit PATH annotation requires a "/" in the beginning (as you can read in this code extracted from the library source:

/** Loads {@link #requestUrl}, {@link #requestUrlParamNames}, and {@link #requestQuery}. */
  private void parsePath(String path) {
    if (path == null || path.length() == 0 || path.charAt(0) != '/') {
      throw methodError("URL path \"%s\" must start with '/'.", path);
    }

The problem that I am facing is that the PATH part comes from the backend in a response object, meaning that all PATH's strings already come formatted from the backend previously in other response as follows:

Object : {
    href: "/resources/login..."
}

As you can see, when including something like this, the URL gets malformed:

@GET("{/loginHref}")
    void login(@EncodedPath("loginHref") String loginHref,
               Callback<User> callback);

to something like "http://mybaseurl.com//resources/login" *double // in front of resources

This can definitely cause issues in some endpoints and I cannot think a really simple way to solve this issue apart from doing something like:

a) Modify my own version of retrofit to remove that / character check (this is a last resort)

b) Truncate the href before using the method from the interface (which I would like to avoid at all cost as well as would add unnecessary transformation all over the place.

c) Intercept the request and correctly form the URL in case this scenario happens (really ugly solution as well).

Any idea, suggestions?

Thanks!

like image 835
Jatago Avatar asked Jun 03 '14 14:06

Jatago


1 Answers

I think this link will help you Path Replacement

Your new implementation will look like this.

@GET("/")
void login(Callback<User> callback);

You can supply a custom Endpoint implementation on which you can change the relative path.

public final class CustomEndpoint implements Endpoint {
  private static final String BASE = "http://192.168.1.64:5050/api/";

  private String url;
  private String href;      

  public CustomEndpoint(String href){
      this.href = href;
      url = BASE + this.href;
  }

  @Override public String getName() {
    return "default";
  }

  @Override public String getUrl() {
    if (url == null) throw new IllegalStateException("relative path not set.");
    return url;
  }
}

Usage is as follows

RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(new CustomEndPoint(object.href));
then restadapter.create........

Hope this will help you.

like image 178
Ashwin N Bhanushali Avatar answered Oct 20 '22 11:10

Ashwin N Bhanushali