Как загрузить изображение на Parse Server, используя Kotlin / Jvm через Rest Service? - PullRequest
0 голосов
/ 10 марта 2019

Я создаю приложение Kotlin / Jvm (без Android Sdk), которое взаимодействует с экземпляром сервера Parse (Back4App). К сожалению, parse не предоставляет реализацию Sdk для использования с Java / Kotlin без Android.

Так что я использую остальные API. Сейчас я пытаюсь загрузить изображение с моего диска на файловый сервер Back4App. В doc есть фрагмент с использованием curl. Но я не смог перевести сервис Retrofit:

curl -X POST \
  -H "X-Parse-Application-Id: 4MGgDJ0ZiQloXoSTE2I9VM6YUYIz8EwCKF4pK7zr" \
  -H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
  -H "Content-Type: image/jpeg" \
  --data-binary '@myPicture.jpg' \
  https://YOUR.PARSE-SERVER.HERE/parse/files/pic.jpg

Итак, я основал свою реализацию в этой статье и других фрагментах из GitHub и создал для нее сервис модернизации:

@Multipart
@POST("/parse/files")
fun upload(
    @Part file: MultipartBody.Part
): Call<ResponseBody>

И звоните:

var file = File("assets/escudo.png")

var requestFile = RequestBody.create(MediaType.parse("**/image"), file)

var body = MultipartBody.Part.createFormData("picture", file.name, requestFile)
var r = getService().upload(body).execute()

Я создал экземпляр модификации, как показано ниже:

fun getService(): ParserService {

    val retrofit = Retrofit
        .Builder()
        .baseUrl("https://parseapi.back4app.com")
        .addConverterFactory(GsonConverterFactory.create())
        .client(createClient()).build()

    return retrofit.create(ParserService::class.java)
}

fun createClient(): OkHttpClient {
    return OkHttpClient.Builder().addInterceptor(createHeadInterceptor()).build()
}

fun createHeadInterceptor(): Interceptor {
    return HeaderInterceptor()
}

class HeaderInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response =
        chain.run {
            val credentials = CredentialsUtils.readCredentials()
            log.info { credentials }
            proceed(
                request().newBuilder()
//                    .addHeader("Content-Type", "application/json")
                     .addHeader("Content-Type", "image/png")
                    .addHeader("X-Parse-Application-Id", credentials.back4appAppId)
                    .addHeader("X-Parse-REST-API-Key", credentials.back4appRestApiKey)
                    .build()
            )
        }
}

Я смог использовать его для публикации данных Json (раскомментировав заголовок содержимого / типа). Но когда я попытался загрузить изображение, я получил этот ответ:

Response{protocol=h2, code=400, message=, url=https://parseapi.back4app.com/parse/files}

enter image description here

Подробнее:

enter image description here

- РЕДАКТИРОВАТЬ

Я пробовал другой подход без Retrofit, он дает код ответа 201 и дает мне objectId, но он не загружает файл:

val file2 = File("assets/escudo.png")
    val serverUrl = "https://parseapi.back4app.com/classes/myfiles"
    val url = URL(serverUrl)
    val conn = url.openConnection() as HttpURLConnection
    conn.requestMethod = "POST"
    conn.doOutput = true

    val postData = file2.readBytes()

    conn.addRequestProperty("Content-length", postData.size.toString())
    conn.setRequestProperty("Content-Type", "image/*")
    conn.setRequestProperty("X-Parse-Application-Id", credentials.back4appAppId)
    conn.setRequestProperty("X-Parse-REST-API-Key", credentials.back4appRestApiKey)

    val outputStream = DataOutputStream(conn.outputStream)
    outputStream.write(postData)
    outputStream.flush()

    println(conn.responseCode)

there should be a new column with the file, right?

- РЕДАКТИРОВАТЬ

Попробуем сейчас с помощью Khttp:

    val file = File("assets/foto.jpg")
    val file2 = File("assets/escudo.png")
    val serverUrl = "https://parseapi.back4app.com/classes/myfiles"


    val files = listOf(FileLike("foto.jpg", file), FileLike("escudo.png", file2))
    val response = post(serverUrl, headers = getHeaders(), files = files)

    println(response)
    println(response.text)

}

fun getHeaders(): Map<String, String> {
    return mapOf(
        "Content-Type" to "image/*",
        "X-Parse-Application-Id" to credentials.back4appAppId,
        "X-Parse-REST-API-Key" to credentials.back4appRestApiKey
    )
}

Получение этой ошибки:

<Response [400]>
{"error":"Unexpected token - in JSON at position 0"}

1 Ответ

1 голос
/ 12 марта 2019

Если вы используете Back4App, правильный URL-адрес сервера:

https://parseapi.back4app.com/files/pic.jpg

...