示例

Http请求从请求方法上可以分为两大类,我们把它们称为Url类请求(UrlRequest)和Body类请求(BodyRequest),因为一类只可以是简单的url,而另一类不仅仅可以是简单的url,也可以使用流来发送自定义RequestBody

Url类的请求方法:

GET, HEAD, OPTIONS, TRACE

Body类的请求方法:

POST, PUT, DELETE, PATCH

在示例中,Url类的请求我们以GET为代表,Body类的请求我们以POST为代表。

对Callback的说明

这里我们先以GET请求方法为例,我们请求一个UserInfo,先写一个完整的请求。。

Kalle.get("http://www.example.com")
    .perform(new Callback<UserInfo, String>() {
        @Override
        public void onStart() {
            // 请求开始了,可以显示个dialog。
        }

        @Override
        public void onResponse(SimpleResponse<UserInfo, String> response) {
            // 请求响应了。
            if(response.isSucceed()) {
                // 业务成功,拿到业务成功的数据。
                UserInfo user = response.succeed();
                ...
            } else {
                // 业务失败,拿到业务失败的数据。
                String message = response.failed();
                ...
            }
            ...
        }

        @Override
        public void onException(Exception e) {
            // 请求发生异常了。
        }

        @Override
        public void onCancel() {
            // 请求被取消了。
        }

        @Override
        public void onEnd() {
            // 请求结束了,可以关闭之前显示的dialog。
        }
    });

一些特点:

  • 回调了onStart(),就肯定会回调onEnd()
  • 回调了onStart(),也可能会回调onCancel(),接着一定会回调onEnd()
  • 没有回调onStart()时,也可能会回调onCancel(),接着一定会回调onEnd()
  • onException()是客户端环境发生异常时回调,比如超时、网络错误、发送数据失败。
  • onResponse()只要服务器有响应就会回调,不论响应码是100、200、300、400、500段中的任何一个。

Kalle中用Callback来回调请求的响应结果,Callback需要两个泛型,第一个泛型表示业务成功时的数据类型,第二个泛型表示业务失败时的数据类型。最终会交给转换器把数据转为开发者指定类型的数据。上述代码中,先抛开onException(Exception)不管,在onResponse(SimpleResponse)中我们希望业务成功时直接拿到UserInfo对象示例,业务失败时返回错误原因。

简化Callback

Kalle中提供了一个SimpleCallback,它是Callback的直接子类,且限定了错误时返回的数据时String,使用它写一个请求就很简单了:

Kalle.get("http://www.example.com")
    .perform(new SimpleCallback<UserInfo>() {
        @Override
        public void onResponse(SimpleResponse<UserInfo, String> response) {
            // 请求响应了。
            if(response.isSucceed()) {
                UserInfo user = response.succeed();
                ...
            } else {
                Toast.show(response.failed());
            }
        }
    });

在上述代码中,我们只传了一个泛型UserInfo就可以请求到UserInfo的实体了,对于业务判断也仅仅需要一个isSucceed()方法即可(不用判断http响应码、业务数据的响应码、数据结构是否符合预期等),当然这个简单的写法并不是臆测的,而是需要我们使用Converter做一些业务封装,请参考业务封装

如果开发者需要处理onException()onCancel()等情况,还需要再重写这几个方法,但是经过业务封装后这几个方法也不需要写了。另外有些业务场景在业务失败时返回的不是一句提示,也就是说不是String,而是另一个对象示例,此时开发者可以参考SimpleCallback写一个自己的Callback类。

Url中的PATH

很多开发者的url中的path段会带有需要encode的字符(例如中文),在Kalle中开发者不需要关注自己的path中是否带有需要encode的字符,例如这样的url是完全没问题的:

http://www.example.com/示例/演示.apk

值得一提的是,Kalle中支持开发者拼接path,例如有些按照RESTFUL风格设计的服务器接口,如果我们要读取用户信息可能是这样:

http://www.example.com/{userId}/info

这样的情况并不少见,在Kalle中我们可以这样写:

String userId = ...;

Kalle.get("http://www.example.com")
    .path(userId)
    .path("info")
    .perform(new SimpleCallback<UserInfo>() {
        @Override
        public void onResponse(SimpleResponse<UserInfo, String> response) {
            // 请求响应了。
            UserInfo = response.result();
        }
    });

简单的GET请求

Kalle.get("http://www.example.com")
    .header("version", 123) // 添加请求头。
    .setHeader("name", "kalle") // 设置请求头,会覆盖默认头和之前添加的头。
    .param("name", "kalle") // 添加请求参数。
    .perform(...);

这里还有一些其它属性可以设置,比如超时时间,代理服务器,SSL证书,域名信任器等等,开发者可以自行探索。

另外值得注意的是,这里添加的参数最终会拼接到url上发送,因为GET请求属于我们之前说过的Url类请求,这样的行为是Http协议规定的。

简单的POST请求

Kalle.post("http://www.example.com")
    .header("version", 123) // 添加请求头。
    .setHeader("name", "kalle") // 设置请求头,会覆盖默认头和之前添加的头。
    .param("name", "kalle") // 添加请求参数。
    .perform(...);

其它的通用设置跟GET请求是一样的,这里不再赘述。

Body类型请求添加参数的两种情况

我们知道Body类型的请求既可以通过RequestBody发送参数,也可以通过url发送参数(以何种方式发送参数取决与服务端与客户端的约定),Kalle同时支持这两种方式。

例如服务端给一个接口:http://www.example.com/user?id={userId}&name={username},需要我们使用POST方法请求,并且需要在RequestBody中发送agesex的参数,那么我们可以这样做:

String userId = ...;
String userName = ...;
int userAge = ...;
int userSex = ...;

Kalle.post("http://www.example.com/user")
    .urlParam("id", userId)
    .urlParam("name", userName)
    .param("age", userAge)
    .param("sex", userSex)
    .perform(...);

服务端的另一个接口:http://www.example.com/user?id={userId},需要我们使用POST方法请求,并且需要在RequestBodypush一段json:

String json = ...;

Kalle.post("http://www.example.com/user")
    .urlParam("id", userId)
    .body(new JsonBody(json))
    .perform(...);

更多关于RequestBody的使用请继续往下看。

表单提交文件

表单上传文件是Http中上传文件最常见的一种,几乎90%的上传文件都以form方式上传的。在Kalle中,在Body类型的请求中,只要添加了File或者Binary参数,会自动以表单的形式发送请求,写法有如下几种:

第一种:

File file = ...;

Kalle.post("http://www.example.com")
    .file("header", file)
    .perform(...);

第二种:

File file = ...;
Binary binary = new FileBinary(file);

Kalle.post("http://www.example.com")
    .binary("header", binary)
    .perform(...);

这样就把一个文件作为名为header的参数的值,以form的形式提交服务器了。

你也可以为header参数提交多个文件(前提是你们服务端支持或者需要),这里有几种方式:

第一种,为一个key添加多次File

File file1 = ...;
File file2 = ...;

Kalle.post("http://www.example.com")
    .file("header", file1)
    .file("header", file2)
    .perform(...);

第二种,添加List<File>:

List<File> fileList = ...;

Kalle.post("http://www.example.com")
    .files("header", fileList)
    .perform(...);

第三种,为一个key添加多次Binary

Binary binary1 = ...;
Binary binary2 = ...;

Kalle.post("http://www.example.com")
    .binary("header", binary1)
    .binary("header", binary2)
    .perform(...);

第四种,添加List<Binary>:

List<Binary> binaries = ...;

Kalle.post("http://www.example.com")
    .binary("header", binaries)
    .perform(...);

提交自定义Body

只要是Body类型的请求都可以提交自定义RequestBody,这是一个示例:

RequestBody body = ...;

Kalle.post("http://www.example.com")
    .body(body)
    .perform(...);

我们看到的RequestBody是一个接口,在Kalle中已经提供了几种默认实现:

FileBody    // 用Body发送文件。
StringBody  // 用Body发送字符串。
JsonBody    // 用Body发送Json字符串。
XmlBody     // 用Body发送Xml字符串。
FormBody    // 用Body模拟发送表单。
UriBody     // 用Body发送Url参数。

例如用RequestBody发送一个文件:

File file = ...;
RequestBody body = new FileBody(file);

Kalle.post("http://www.example.com")
    .body(body)
    .perform(...);

例如用RequestBody发送一段字符串:

RequestBody body = new StringBody("I like you.");

Kalle.post("http://www.example.com")
    .body(body)
    .perform(...);

发送JsonXml的同发送String一样:

String json = ...;

RequestBody body = new JsonBody(json);

Kalle.post("http://www.example.com")
    .body(body)
    .perform(...);
String xml = ...;

RequestBody body = new XmlBody(xml);

Kalle.post("http://www.example.com")
    .body(body)
    .perform(...);

UrlBody是在Body类型的请求没有添加FileBinary时内部自动转换使用的,一般开发者不会使用到,如果开发者想用也是可以的:

UrlBody body = UrlBody.newBuilder()
    .param("name", "Kalle")
    .param("age", 18)
    .param("sex", 1)
    .build();

Kalle.post("http://www.example.com")
    .body(body)
    .perform(...);

FormBody是在需要以表单实行发送参数时使用的。前面有说到过,Body类型的请求,只要添加了File或者Binary就会自动转化为表单的形式提交也是使用的FormBody。要特别说明的是,有些开发者需要在没有文件的时候也使用表达发送参数,那么我们可以这样做:

File file = ...;

FormBody body = FormBody.newBuilder()
    .param("name", "Kalle")
    .param("age", 18)
    .param("sex", 1)
    .file("header", file)
    .build();

Kalle.post("http://www.example.com")
    .body(body)
    .perform(...);

results matching ""

    No results matching ""