Android开发经验谈Android开发Android知识

Retrofit2 的baseUrl 真的必须以 /(斜线) 结

2017-10-25  本文已影响1010人  闲庭

【Retrofit GitHub】: https://github.com/square/retrofit
版本:2.4.0

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(baseUrl)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

最近刚好想看看Retrofit源码了,之前看过好多博文都提到注意Retrofit2 的baseUrl 必须以 /(斜线) 结束,不然会抛出一个IllegalArgumentException异常
个人感觉这段话说的不严谨,并不是所有的baseUrl不以 /(斜线) 结尾就会抛出一个IllegalArgumentException异常,这里就需要讲述一下Url的格式了,往往一个Url格式为scheme://host[:port]/path[?query],

public static final String API_URL = "https://api.github.com";
public interface GitHub {
    @GET("/repos/{owner}/{repo}/contributors")
    Call<List<Contributor>> contributors(
        @Path("owner") String owner,
        @Path("repo") String repo);
  }

现在以https://api.github.com/repos/{owner}/{repo}/contributors这个接口为例,此处的

关于Retrofit中的baseUrl并没有强制怎么写,我可以写成https://api.github.com也可以写成 https://api.github.com/repos/,区别在哪呢?下面听我仔细说:

  1. https://api.github.com的格式可以看成scheme://host[:port](此种类型是不是以 /(斜线) 结尾都可以,均不会抛出IllegalArgumentException异常);
  2. https://api.github.com/repos/的格式可以看成scheme://host[:port]/path(此种类型必须以/(斜线) 结尾,否则会抛出IllegalArgumentException异常).

下面关于baseUrl的问题来看看Retrofit.java中的源码:

public Builder baseUrl(String baseUrl) {
     checkNotNull(baseUrl, "baseUrl == null");
     HttpUrl httpUrl = HttpUrl.parse(baseUrl);
     if (httpUrl == null) {
       throw new IllegalArgumentException("Illegal URL: " + baseUrl);
     }
     return baseUrl(httpUrl);
 }
​
public Builder baseUrl(HttpUrl baseUrl) {
     checkNotNull(baseUrl, "baseUrl == null");
     List<String> pathSegments = baseUrl.pathSegments();
     if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
       throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
     }
     this.baseUrl = baseUrl;
     return this;
 }

可以看到第二个baseUrl方法中会在一定场景下抛出IllegalArgumentException异常,但是在第一个baseUrl方法中HttpUrl.parse(baseUrl)会对baseUrl做处理转换成对应的HttpUrl,区别就在这里了,对于场景1中https://api.github.com会自动转换成https://api.github.com/,如下图:

场景1.png

而场景2中自然不会做处理,若场景2中写成https://api.github.com/repos未以 /(斜线) 结尾,此时HttpUrl.parse(baseUrl)也不会对此做处理,那么就会抛出IllegalArgumentException异常。如下图:

场景2.png 抛异常.png

注意:建议BaseUrl以/(斜线) 结尾。scheme://host[:port]/path类型的baseUrl必须以/(斜线) 结尾。

路径整合规则:

BaseUrl Path形式 Path对应的值 最后Url
http://host:port/a/b/ 绝对路径 /apath http://host:port/apath
http://host:port/a/b/ 相对路径 apath http://host:port/a/b/apath
http://host:port/a/b/ 完整路径 http://host:port/aa/apath http://host:port/aa/apath
上一篇下一篇

猜你喜欢

热点阅读