关于android:如何发送带有json组成部分的OkHttp发布请求以及图像文件

How to send OkHttp post request with json multipart body along with a image file

我想发送一个发布请求,其中必须发送一些数据,其中包括json格式的数据和图像文件。

当我分别发送请求时,它可以正常工作,但不会一起唤醒。

请在这里帮助我,如何实现这一目标。

我用来发送json格式数据的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Map<String, String> map = new HashMap<>();
postParam.put("title","XYZ");
postParam.put("isGroup","true");
postParam.put("ownerId","123");
JSONArray jsonArray = new JSONArray();
jsonArray.put("1");
jsonArray.put("2");
jsonArray.put("2");
postParam.put("groupMembers", jsonArray.toString());
MediaType JSON = MediaType.parse("application/json");
JSONObject parameter = new JSONObject(postParam);
RequestBody body = RequestBody.create(JSON, parameter.toString());
Request request = new Request.Builder()
            .url(postUrl)
            .addHeader("content-type","application/json; charset=utf-8")
            .post(body)
            .build();

当我不使用该文件时,它可以正常工作。
但是我必须通过此请求将图像文件作为多部分数据发送,然后再执行。


kotlin用法

尝试使用这段代码。就我而言,它奏效了。并让我知道它是否有效,并做出正确的答案(:

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
37
38
    private const val CONNECT_TIMEOUT = 15L
    private const val READ_TIMEOUT = 15L
    private const val WRITE_TIMEOUT = 15L

    private fun performPostRequest(urlString: String, jsonString: String, image: File, token: String): String? {
        /* https://github.com/square/okhttp#requirements
        OkHttp uses your platform's built-in TLS implementation.
        On Java platforms OkHttp also supports Conscrypt,
        which integrates BoringSSL with Java.
        OkHttp will use Conscrypt if it is the first security provider: */
        Security.insertProviderAt(Conscrypt.newProvider(), 1)

        return try {
            val client = OkHttpClient.Builder()
                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                .build()

            val body: RequestBody = MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("parameterNameInServerSideJSON", jsonString)
                .addFormDataPart("parameterNameInServerSideImage","test.jpeg", image.asRequestBody("image/jpg".toMediaTypeOrNull()))
                .build()

            val request = Request.Builder()
                .url(URL(urlString))
                .header("Authorization", token) // in case you use authorization
                .post(body)
                .build()

            val response = client.newCall(request).execute()
            response.body?.string()
        }
        catch (e: IOException) {
            e.printStackTrace()
            null
        }
    }

我已使用此版本的okhttp

1
    implementation 'com.squareup.okhttp3:okhttp:4.3.1'

尝试使用此命令发送文件:

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
public void addFilePart(String fieldName, File uploadFile)
            throws IOException {
        String fileName = uploadFile.getName();
        writer.append("--" + boundary).append(LINE_FEED);
        writer.append(
               "Content-Disposition: form-data; name="" + fieldName
                        +""; filename="" + fileName +""")
                .append(LINE_FEED);
        writer.append(
               "Content-Type:"
                        + URLConnection.guessContentTypeFromName(fileName))
                .append(LINE_FEED);
        writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
        writer.append(LINE_FEED);
        writer.flush();

        FileInputStream inputStream = new FileInputStream(uploadFile);
        byte[] buffer = new byte[4096];
        int bytesRead = -1;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
        inputStream.close();

        writer.append(LINE_FEED);
        writer.flush();
    }