首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >已生成的亚马逊网络服务signedUrl不支持安卓Retrofit2 call上传视频(Mp4)

已生成的亚马逊网络服务signedUrl不支持安卓Retrofit2 call上传视频(Mp4)
EN

Stack Overflow用户
提问于 2021-03-28 14:57:25
回答 1查看 109关注 0票数 1

我有一个来自AWS的签名url。

我使用下面的代码上传我的mp4文件。

代码语言:javascript
复制
 val retrofit = Retrofit.Builder()
            .baseUrl("https://www.DUMMEY.com/") // THIS BASE URL AUTOMATICALLY REPLACE ONCE RETROFIT INTERFACE BODY ATTACH WITH @URL
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()

        val videoInterface = retrofit.create(
            FileUploadService::class.java
        )

        var apiResponse: Call<Void>
        val requestBody = activity.contentResolver.readAsRequestBody(fileUri)
        apiResponse = videoInterface.upload(
            "video/mp4",
            "Android-OS",
            signedurl,
            requestBody
        )
        apiResponse.enqueue(object : Callback<Void> {
            override fun onResponse(
                call: Call<Void>,
                response: Response<Void>
            ) {
                Log.d("SUCCESS", "=========API RESPONE SUCCESS=========" + apiResponse)
            }

            override fun onFailure(call: Call<Void>, t: Throwable) {
                Log.e("FAILED", "=========API RESPONE FAILED=========" + apiResponse)
            }

        })
    }.start()



fun ContentResolver.readAsRequestBody(uri: Uri): RequestBody =
    object : RequestBody() {
        override fun contentType(): MediaType? =
            this@readAsRequestBody.getType(uri)?.toMediaTypeOrNull()

        override fun writeTo(sink: BufferedSink) {
            this@readAsRequestBody.openInputStream(uri)?.source()?.use(sink::writeAll)
        }

        override fun contentLength(): Long =
            this@readAsRequestBody.query(uri, null, null, null, null)?.use { cursor ->
                val sizeColumnIndex: Int = cursor.getColumnIndex(SIZE)
                cursor.moveToFirst()
                cursor.getLong(sizeColumnIndex)
            } ?: super.contentLength()
    }

interface FileUploadService {
@PUT
fun upload(
    @Header("Content-Type") contentType: String?,
    @Header("User-Agent") userAgent: String?,
    @Url signingUrl: String?,
    @Body file: RequestBody
): Call<Void>

}

但是,我还是不能成功。

在运行代码时,我一直收到"javax.net.ssl.SSLException: Write error: ssl=0xe8abb908: I/O error during system call,Broken“这个错误。(但我觉得这不仅仅是一个SSLException,而且我的代码中也有一个巨大的错误)

根据Postman的输出,它应该响应"1“和200OK。

我也使用这段代码为我的文件添加了"Multipart.Part“。

代码语言:javascript
复制
   val file = File(fileUri!!.path!!)
   val requestBody = InputStreamRequestBody(activity.contentResolver, fileUri)
   val filePart = MultipartBody.Part.createFormData("file", file.name, requestBody)

接口是..

代码语言:javascript
复制
 @Multipart
@PUT
fun uploadHope(
    @Header("Content-Type") contentType: String?,
    @Header("User-Agent") userAgent: String?,
    @Url signingUrl: String?,
    @Part file: MultipartBody.Part
): Call<Void>

出现相同的错误。

我关注了这个blog作为帮助。

请帮我“上传成功”这一点。

EN

回答 1

Stack Overflow用户

发布于 2021-04-02 02:23:43

我做了一个很大的调查,但失败了。Retrofit2似乎不支持这种亚马逊网络服务signedUrl上传。但是我用“HttpUrlConnection”的方式成功了。通常我们使用。

代码语言:javascript
复制
 private static final int BUFFER_SIZE = 1024 * 1024 * 10;



 fun uploadFile(signedurl: String? = null, filePath: String? = null) {
    Thread {
        var serverResponseCode = -1
        try {
            var url: URL? = null
            url = URL(signedurl)
            val connection = url.openConnection() as HttpURLConnection
            connection.doOutput = true
            connection.requestMethod = "PUT"
            connection.setRequestProperty("Content-Type", " ") // Very important ! It won't work without adding this!
            var dos: DataOutputStream? = null
            var bytesRead: Int
            var bytesAvailable: Int
            var bufferSize: Int
            var buffer: ByteArray
            val sourceFile: File = File(filePath)
            try {
                FileInputStream(sourceFile).use { fileInputStream ->
                    dos = DataOutputStream(connection.outputStream)
                    bytesAvailable = fileInputStream.available()
                    bufferSize = Math.min(
                        bytesAvailable,
                        BUFFER_SIZE
                    )
                    buffer = ByteArray(bufferSize)
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize)
                    while (bytesRead > 0) {
                        dos!!.write(buffer, 0, bufferSize)
                        bytesAvailable = fileInputStream.available()
                        bufferSize = Math.min(
                            bytesAvailable,
                            BUFFER_SIZE
                        )
                        bytesRead = fileInputStream.read(buffer, 0, bufferSize)
                    }
                }
            } catch (e: Exception) {
                Log.e("Log", "error " + e)
            } finally {
                // close the streams
                if (dos != null) {
                    dos!!.flush() //send any left data
                    dos!!.close()
                }
            }
            serverResponseCode = connection.responseCode
            Log.e("response", "response code " + serverResponseCode)
        } catch (e: Exception) {
            Log.e("Log", "error " + e)
        }
    }.start()
}

如果您遵循此方法,请突出显示这些行,

代码语言:javascript
复制
var url: URL? = null
            url = URL(signedurl)
            val connection = url.openConnection() as HttpURLConnection


connection.setRequestProperty("Content-Type", " ") // Very important ! It won't work without adding this!

注意:-在某些情况下,此服务可能会响应200 (Ok),但内容可能无法上载。因为亚马逊网络服务的S3存储桶只接受文件对象,所以它不检查可用的内容,也不只回复200。因此,如果发生此错误,请联系服务器,首先查看错误是什么。

如果有人找到通过retrofit2上传到亚马逊网络服务的方法。请在这里回答。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66839105

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档