如何使用Okhttp来post数据
本教程将介绍如何使用OkHttp来post,这是一个用于Android和Java应用程序的HTTP和HTTP / 2客户端。 我们将介绍一些常用的用例和示例,例如如何发布字符串,如何发布表单,如何发布文件流等等。
1、准备
我们将在教程中使用OkHttp,所有OkHttp的post示例都是基于3.5.0版本的,我们需要的唯一Maven依赖项是:
maven:
1 2 3 4 5 |
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.5.0</version> </dependency> |
gradle:
1 |
implementation 'com.squareup.okhttp3:okhttp:3.5.0' |
okhttp官方网址:https://square.github.io/okhttp/
一个post的内容格式示例:
1 2 3 4 5 6 7 8 9 |
--35acdf5f-ddf8-4803-bb55-5a3254258c23 Content-Disposition: form-data; name="data"; filename="file-name" Content-Type: binary/octet-stream Content-Length: 425 �U�Mn�0��h�R�"�;��Y8.�*(���ȔAJn���p6]�]�q�Egd)E��y�� ��Hm6S�"F�>D�m�nQG��Hi=�zu��=n,x��Wmi����P�ij���tݺ�����m1Y�z?�HP]~�"�c���u]9�k�1x~sѬ�?~�4>�}���:��� 0��S��]�1��,�JM� "3Ui�d��� K��3��Y��8[�'�AÝ��j�'�b�Tq0�7��҅FUլ����PA8?at$�(A<��z��4f �W(^�ua%�Rł$Bk"�(H�dJ�`�-�1ZI�ۭu �1��+*�Ÿʫu�5P�c���Z�U^�?c�a��o��x���^?�����k���{�G0L�j 4��-X�ιH�YNw�3�1| --35acdf5f-ddf8-4803-bb55-5a3254258c23-- |
2、Okhttp 来 post String 字符串
让我们看一个下面的例子,我们将使用OkHttpClient发布一个带OkHttp的字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public void testPostingWithString() throws IOException { OkHttpClient client = new OkHttpClient.Builder().build(); MediaType textPlainMT = MediaType.parse("text/plain; charset=utf-8"); String helloMsg = "Hello OkHttp"; Request request = new Request.Builder().url("https://httpbin.org/post") .post(RequestBody.create(textPlainMT, helloMsg)).build(); Response response = client.newCall(request).execute(); assertTrue(response.isSuccessful()); response.close(); } |
在该示例中,在创建client实例后,我们通过向构建器提供远程服务器的URL,HTTP Post方法和请求body来创建一个request请求。 请注意我们如何通过提供要发布的文本及其媒体类型来创建请求正文。
由于整个请求body同时在内存中,我们应该避免使用此API发布大型(大于1 MiB)的数据。
3、Post 字节数组
使用OkHttp发布一个字节数组很容易。 以下是我们将字节数组发布到RESTful Web服务的示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private static final MediaType MEDIA_TYPE_PLAINTEXT = MediaType .parse("text/plain; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); @Test public void testPostByteArray() throws Exception { String st = "posting a byte array with OkHttp"; Request request = new Request.Builder() .url("https://httpbin.org/post") .post(RequestBody.create(MEDIA_TYPE_PLAINTEXT, st.getBytes("UTF8"))) .build(); Response response = client.newCall(request).execute(); assertTrue(response.isSuccessful()); } |
4、Post 表单
OkHttp允许我们使用FormBody.Builder发布表单参数,以构建一个像HTML <form>标签一样效果的请求body主体。 名称和值将使用HTML兼容的格式URL encoding编码进行编码。 让我们看一个示例,我们将使用OkHttpClient使用OkHttp发布表单参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
private final OkHttpClient client = new OkHttpClient(); @Test public void testPostForm() throws Exception { RequestBody formBody = new FormBody.Builder() .add("email", "user@howtoprogram.xyz") .add("firstname", "John").add("lastname", "Henry").build(); Request request = new Request.Builder().url("https://httpbin.org/post") .post(formBody) .build(); Response response = client.newCall(request).execute(); assertTrue(response.isSuccessful()); } |
在示例中,我们刚刚使用FormBody.builder创建了一个包含3个字段的表单:email,firstname,lastname,然后将表单发布到远程URL。
5、Post 一个文件
使用OkHttp发布文件非常简单。 我们可以使用RequestBody类来创建传输文件内容的请求body主体。 让我们看看下面的例子,我们将使用OkHttpClient post一个文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private static final MediaType MEDIA_TYPE_PLAINTEXT = MediaType .parse("text/plain; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); @Test public void testPostFile() throws Exception { File file = new File("src/test/resources/Lorem Ipsum.txt"); Request request = new Request.Builder() .url("https://httpbin.org/post") .post(RequestBody.create(MEDIA_TYPE_PLAINTEXT, file)) .build(); Response response = client.newCall(request).execute(); assertTrue(response.isSuccessful()); } |
在上面的示例中,我们已将Lorem Ipsum.txt文件post到RESTful Web服务。
6、Post 一个stream 流
使用OkHttp,我们可以将body请求主体作为流发布。 该请求正文的内容正在编写时生成。 让我们看一个我们将流发布到REST API的示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
private static final MediaType MEDIA_TYPE_PLAINTEXT = MediaType .parse("text/plain; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); @Test public void testPostStream() throws Exception { RequestBody requestBody = new RequestBody() { @Override public MediaType contentType() { return MEDIA_TYPE_PLAINTEXT; } @Override public void writeTo(BufferedSink sink) throws IOException { File file = new File("src/test/resources/Lorem Ipsum.txt"); try (BufferedReader br = new BufferedReader(new FileReader(file))) { String line; while ((line = br.readLine()) != null) { sink.writeUtf8(line); } } } }; Request request = new Request.Builder() .url("http://httpbin.org/post") .post(requestBody) .build(); Response response = client.newCall(request).execute(); assertTrue(response.isSuccessful()); } |
在该示例中,我们通过创建新的RequestBody并覆写writeTo方法来发布流,在该方法中,我们逐行读取文件Lorem Ipsum.txt并将其流式传输到请求的缓冲接收器中。
7、Post 一个 Multipart 请求
我们可以使用MultipartBody.Builder类来构建与HML文件上传表单兼容的body请求主体。 我们可以利用此功能通过OkHttp上传文件和图像。 让我们看一个示例,我们将一个multipart请求发布到RESTful Web服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
private static final MediaType MEDIA_TYPE_PLAINTEXT = MediaType .parse("text/plain; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); @Test public void testPostMultipart() throws IOException { File file = new File("src/test/resources/Lorem Ipsum.txt"); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", "LoremIpsum.txt", RequestBody.create(MEDIA_TYPE_PLAINTEXT, file)) .addFormDataPart("description", "Just Lorem Ipsum") .build(); Request request = new Request.Builder() .url("https://httpbin.org/post") .post(requestBody).build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) { throw new IOException("Unexpected code " + response); } } |
在该示例中,我们创建了MultipartBody类的实例,该实例是符合RFC 2387的请求。 然后我们将一个文件部分和一个描述部分添加到请求体,最后我们执行请求将表单post到RESTful Web服务。
更多content-type和header设置可以参考这里:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Type
I have to thank you for the efforts you have put in penning this website.
I am hoping to see the same high-grade content from you in the future
as well. In fact, your creative writing abilities has encouraged me to get my own, personal website now 😉