如何使用Retrofit2 / rxjava将图像/文件上传到预先签名的s3 url?

时间:2018-11-24 06:01:46

标签: kotlin rx-java retrofit2 okhttp

我能够使用纯okhttp代码上载文件,但不能完全使用Retrofit2复制文件,我不希望输入凭据,因为在okhttp情况下不需要这样做,因此此处不要求好(我想)。 以下是我的okhttp代码。

val client = OkHttpClient()
val file = File(pathOfFileToSend)
val requestFile = okhttp3.RequestBody.create(okhttp3.MediaType.parse("image/jpeg"), file)
val body = MultipartBody.Builder()
for (field in mS3Params!!.post_params!!.fields) {
    body.addFormDataPart(field.name ?: "", field.value ?: "")
}
body.addPart(Headers.of("Content-Disposition", "form-data; name=\"file\""),requestFile)
val request = Request.Builder()
                .url(BuildConfig.S3_IMAGE_SERVER_URL)
                .post(body.build())
                .build()
val response = client.newCall(request).execute()
if (!response.isSuccessful) {
   //Success
} else {
   //Fail
}

上面的代码工作得很好。也共享我的mS3Params以供参考。

class S3ImageParamsResponseModel {
var action: String? = null
var card_id: String? = null
var image_url: String? = null
var post_params: PostParams? = null

class PostParams {
    lateinit var fields: List<Field>

    override fun toString(): String {
        return "PostParams{" +
                "fields=" + fields +
                '}'.toString()
    }
}

class Field {
    var name: String? = null
    var value: String? = null

    override fun toString(): String {
        return "Field{" +
                "name='" + name + '\''.toString() +
                ", value='" + value + '\''.toString() +
                '}'.toString()
    }
}

override fun toString(): String {
    return "S3ImageParamsResponseModel{" +
            "action='" + action + '\''.toString() +
            ", card_id='" + card_id + '\''.toString() +
            ", image_url='" + image_url + '\''.toString() +
            ", post_params=" + post_params!!.toString() +
            '}'.toString()
}

现在,我无法将以上内容转换为Retrofit2 / rxjava请求。我的代码总是给出405异常。这是两个试验。

试验1-

val file = File(pathOfFileToSend)
        Timber.d(TAG, "onRun: length=" + file.length())

        val descriptionPart = RequestBody.create(MultipartBody.FORM, "imageFile")

        val requestFile = RequestBody.create(MediaType.parse("image/jpeg"), file)

        val filePart = MultipartBody.Part.createFormData("photo", "imageFile",
                requestFile)

        val httpClient = OkHttpClient.Builder()
        httpClient.addNetworkInterceptor(StethoInterceptor())
        val client = httpClient.build()
        val retrofit = Retrofit.Builder()
                .baseUrl(BuildConfig.S3_IMAGE_SERVER_URL)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build()
        val uploadService = retrofit.create(FreshClient::class.java)
        val uploads = uploadService.uploadFile(mS3Params!!.image_url!!,
                descriptionPart, filePart)

        uploads.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : DisposableObserver<ResponseBody>() {
                    override fun onComplete() {

                    }

                    override fun onError(e: Throwable) {
                        Timber.d("", "")
                    }

                    override fun onNext(uploadData: ResponseBody) {
                        Timber.d("", "")
                    }
                })

试验2-

val file = File(pathOfFileToSend)
        Timber.d(TAG, "onRun: length=" + file.length())

        val descriptionPart = RequestBody.create(MultipartBody.FORM, "imageFile")

        val requestFile = RequestBody.create(MediaType.parse("image/jpeg"), file)

        val body = MultipartBody.Builder()

        for (field in mS3Params!!.post_params!!.fields) {
            body.addFormDataPart(field.name ?: "", field.value ?: "")
        }

        body.addPart(
                Headers.of("Content-Disposition", "form-data; name=\"file\""),
                requestFile)

        val httpClient = OkHttpClient.Builder()
        httpClient.addNetworkInterceptor(StethoInterceptor())
        val client = httpClient.build()
        val retrofit = Retrofit.Builder()
                .baseUrl(BuildConfig.S3_IMAGE_SERVER_URL)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build()
        val uploadService = retrofit.create(FreshClient::class.java)
        val uploads = uploadService.uploadFile(mS3Params!!.image_url!!,
                descriptionPart, body.build().part(0))

        uploads.subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : DisposableObserver<ResponseBody>() {
                    override fun onComplete() {

                    }

                    override fun onError(e: Throwable) {
                        Timber.d("", "")
                    }

                    override fun onNext(uploadData: ResponseBody) {
                        Timber.d("", "")
                    }
                })

在这两种情况下,我的服务如下-

@Multipart
@POST("")
fun uploadFile(@Url url: String,
               @Part("description") description: RequestBody,
               @Part file: MultipartBody.Part): Observable<ResponseBody>

请帮忙将如何将正常的okhttp代码转换为retrofit2 / rxjava。

0 个答案:

没有答案