Многокомпонентный запрос на отправку изображения на сервер не работает - PullRequest
0 голосов
/ 02 октября 2018

Я сделал многокомпонентный запрос на сервер для отправки изображений из телефонной галереи в соответствии с руководством, но я не знаю, что с ним не так.Сервер вернет код ответа 201, но изображение отправлено на сервер неправильно.

Вот функция HTTPRequest для отправки изображения.

fun doPostImage(resources: String, avatarImage: ByteArray, fileName: String): JSONObject{
        val url = SERVER_URL + resources
        val maxBufferSize = 1024 * 1024

        val X_SESSION: String? = context?.getSharedPreferences(context.
                getString(R.string.SharedPrefs), MODE_PRIVATE)?.
                getString(context.getString(R.string.X_SESSION), null)
        createLog("AvatarRequestURL", "POST $url")
        val obj = URL(url)

        val attachmentName = fileName
        val attachmentFileName = fileName + ".jpg"
        val crlf = "\r\n"
        val twoHyphens = "--"
        val boundary = "*****"


        with(obj.openConnection() as HttpURLConnection) {


            requestMethod = "POST"
            doOutput = true
            doInput = true

            val postData: ByteArray = avatarImage

            if (X_SESSION != null){
                createLog("DOPOST-SESSION", X_SESSION)
                setRequestProperty("X-Session", X_SESSION)
            } else {
                createLog("DOPOST-SESSION", "SESSION NULL :(")
            }

            setRequestProperty("Connection", "Keep-Alive")
            setRequestProperty("Cache-Control", "no-cache")
            setRequestProperty("X-API-Key", API_KEY)
            setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary)
            setChunkedStreamingMode(maxBufferSize)

            //constructing request body
            try {
                val writer = PrintWriter(OutputStreamWriter(outputStream, "UTF-8"), true)
                writer.append(twoHyphens + boundary + crlf)
                writer.append("Content-Disposition: form-data; name=\"" + attachmentName + "\";filename=\"" + attachmentFileName + "\"" + crlf)
                writer.append("Content-Type", "image/jpeg")
                writer.append(crlf)
                writer.flush()

                val byteArrayInputStream = ByteArrayInputStream(postData)
                byteArrayInputStream.copyTo(outputStream, maxBufferSize)

            } catch (exception: Exception) {
                createLog("AvatarImageException", exception.toString())
            }

            createLog("Avatar_Upload_Response", "Response Code Image: $responseCode")

            //server response handling
            if (responseCode != HttpURLConnection.HTTP_OK) {
                try {
                    BufferedReader(InputStreamReader(errorStream)).use {
                        val response = StringBuffer()

                        var inputLine = it.readLine()
                        while (inputLine != null) {
                            response.append(inputLine)
                            inputLine = it.readLine()
                        }
                        createLog("AvatarRequest", "Response body Image: $response")
                        return JSONObject(response.toString())
                    }

                } catch (exception: Exception) {
                    return if(responseCode == HttpURLConnection.HTTP_CLIENT_TIMEOUT){
                        createLog("POST EXCEPTION", exception.toString())
                        val errorResponse = JSONObject()
                        errorResponse.put("ErrorCode", responseCode)
                        errorResponse.put("Message", exception.message)
                        errorResponse
                    } else {
                        createLog("EXCEPTION", exception.toString())
                        val errorResponse = JSONObject()
                        errorResponse.put("ErrorCode", responseCode)
                        errorResponse.put("Message", exception.message)
                        return errorResponse
                    }

                }
            } else {
                try {
                    BufferedReader(InputStreamReader(inputStream)).use {
                        val response = StringBuffer()

                        var inputLine = it.readLine()
                        while (inputLine != null) {
                            response.append(inputLine)
                            inputLine = it.readLine()
                        }

                        createLog("AvatarRequest", "Response body Image: $response")
                        return JSONObject(response.toString())
                    }

                } catch (exception: Exception) {
                    throw Exception("Exception while push the notification  $exception")
                }
            }
        }
    }

Вот как я получаю изображение из галереи:

profilePhotoSelectButton.setOnClickListener {
            val galleryIntent = Intent()
            galleryIntent.type = "image/*"
            galleryIntent.action = Intent.ACTION_GET_CONTENT
            startActivityForResult(Intent.createChooser(galleryIntent, "Choose profile photo"), PICK_PHOTO)

        }

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == PICK_PHOTO){

            val avatarPhoto: Uri? = data?.data
            if (avatarPhoto != null){
                val imageStream: InputStream = contentResolver.openInputStream(avatarPhoto)
                val imageBitmap: Bitmap = BitmapFactory.decodeStream(imageStream)
                val roundedBitMapDrawable: RoundedBitmapDrawable = RoundedBitmapDrawableFactory.create(resources, imageBitmap)
                roundedBitMapDrawable.isCircular = true
                profilePhotoPreview.setImageDrawable(roundedBitMapDrawable)

                val userPhotoToJSON: Bitmap = MediaStore.Images.Media.getBitmap(this.contentResolver, avatarPhoto)
                val resizedBitmap: Bitmap = getResizedBitmap(userPhotoToJSON, 150)
                userProfilePhotoEncoded = compressBitmap(resizedBitmap, Bitmap.CompressFormat.JPEG)
                userProfilePhotoPath = avatarPhoto.path
                createLog("AvatarPath ", userProfilePhotoPath.toString())
                userProfilePhotoName = File(avatarPhoto.path).name
                createLog("AvatarName ", userProfilePhotoName.toString())
            }
        }
    }

    private fun compressBitmap(bitmapPicture: Bitmap, compressFormat: Bitmap.CompressFormat): ByteArray {
        val COMPRESSION_QUALITY = 50
        val byteArrayBitmapStream = ByteArrayOutputStream()
        bitmapPicture.compress(compressFormat, COMPRESSION_QUALITY, byteArrayBitmapStream)
        val avatarByteArray: ByteArray = byteArrayBitmapStream.toByteArray()
        return avatarByteArray
    }

    /**
     * reduces the size of the image
     * @param image
     * @param maxSize
     * @return
     */
    fun getResizedBitmap(image: Bitmap, maxSize: Int): Bitmap {
        var width = image.width
        var height = image.height

        val bitmapRatio = width.toFloat() / height.toFloat()
        if (bitmapRatio > 1) {
            width = maxSize
            height = (width / bitmapRatio).toInt()
        } else {
            height = maxSize
            width = (height * bitmapRatio).toInt()
        }
        return Bitmap.createScaledBitmap(image, width, height, true)
    }


api.updateAvatar(userProfilePhotoEncoded!!,userProfilePhotoPath!!, userProfilePhotoName!!, object: IProfileCallback{
                            override fun onError(errorJSON: JSONObject) {
                                createLog("AVATAR_ERROR ", errorJSON.toString())
                            }

                            override fun onSuccess(profileJSON: JSONObject?) {
                                createLog("AVATAR SUCCESS", profileJSON.toString())
                                setResult(MYDATA_UPDATE_RESULT)
                                finish()
                            }

                        })

fun updateAvatar(avatar: ByteArray, filepath: String, fileName: String, callback: IProfileCallback){

        class UpdateProfileAsync(private val profileCallback: IProfileCallback): AsyncTask<Void, Void, JSONObject>() {

            override fun doInBackground(vararg p0: Void?): JSONObject {

                val server = Server.getInstance(context!!)

                return server.doPostImage(context.getString(R.string.profile_avatar_link), avatar, fileName)
            }

            override fun onPostExecute(result: JSONObject?) {
                super.onPostExecute(result)

                if(result!!.has("ErrorCode")){
                    profileCallback.onError(result)
                } else {
                    createLog("SuccessfullyUpdatedProfile", "onSuccess()")
                    profileCallback.onSuccess(result)
                }
            }
        }

        UpdateProfileAsync(callback).execute()
    }
...