How to make a post request using Okio? - android

I'm using Okio to download a file....with my request i'm sending some parameters, but since I wasn't getting my file and I was able to log my request and this is what is see:
Why tags is null? that means that the parameters are null
Request: Request{method=POST, url=https://mywesite.com/, tag=null}
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("user", "test")
.addFormDataPart("pass", "1234")
.build();
Request request = new Request.Builder()
.url(imageLink)
.post(requestBody)
.build();

Here is example:
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
from: https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/guide/PostExample.java

Related

upload audio file with binary body with retrofit

I need to upload audio file with binary body with retrofit like the image bellow in postman:
how can i upload audio file with binary body like the image with retrofit?
This is what I did but its not work:
#Multipart
#POST("upload")
fun uploadAudio(
#Part audio_file: MultipartBody.Part
): Call<ModelGetAudioUrl>
And this is how I prepare audio file for multipartbody.Part:
According to your screenshot, you propably don't want to use a multipart body. So something like
#POST("upload")
fun uploadAudio(#Body audio_file: TypedInput): Call<ModelGetAudioUrl>
or #Body audio_file: RequestBody should work (see How to send byte[] array in retrofit).
I solve it by using okhttp:
val client = OkHttpClient().newBuilder()
.callTimeout(90, TimeUnit.SECONDS)
.readTimeout(90, TimeUnit.SECONDS)
.connectTimeout(90, TimeUnit.SECONDS)
.writeTimeout(90, TimeUnit.SECONDS)
.build();
val mediaType = "audio/wave".toMediaTypeOrNull();
val body = RequestBody.create(mediaType, soundFile)
val request = Request.Builder()
.url("https://api.assemblyai.com/v2/upload")
.method("POST", body)
.addHeader("authorization", "99fa2a59e27e4688b9f7edcdc8ed7185")
.addHeader("Transfer-Encoding", "chunked")
.addHeader("Content-Type", "audio/wave")
.build()
Thread {
try {
val response = client.newCall(request).execute().use {
if (it.isSuccessful) {
val str = it.body?.string()
if (!str.isNullOrEmpty()) {
val json = JSONObject(str)
sendUrlToTranscript(json.getString("upload_url"))
}
}
context.runOnUiThread {
if (!it.isSuccessful) {
loading.hideDialog()
}
}
}
}catch (e: Exception) {
e.printStackTrace()
Log.d("uploadAudio", "uploadAudio: ${e.message}")
}
}.start()

Api call with basic auth and headers working with okhttp but not working with retrofit

I have an api call with basic auth, multiple headers and request body. But my request is not working with retrofit. So just to verify I checked with okhttp and it is working.
Below is my retrofit code
Api Interface
#POST("login")
suspend fun login(#HeaderMap headers:HashMap<String,String>, #Body body: RequestBody): retrofit2.Response<Any>
Retrofit Instance
#Singleton
#Provides
fun injectRetrofitAPI() : ApiInterface {
val logging = HttpLoggingInterceptor()
logging.level = HttpLoggingInterceptor.Level.BODY
val client = OkHttpClient.Builder()
.addInterceptor(logging)
.build()
return Retrofit.Builder().client(client)
.addConverterFactory(MoshiConverterFactory.create())
.baseUrl(AppConstants.BASE_URL).build().create(ApiInterface::class.java)
}
This is how I am creating my headers and body
private fun createParameters() {
headers["db"] = "P"
headers["latitud"] = "0"
headers["longitud"] = "0"
headers["apiKey"] = "a9f1b3fd3d5a62782f24d2d00afe4532"
headers["Content-Type"] = "application/json"
val credentials = String.format("%s:%s", "centro", "Salud1011.")
val auth = "Basic " + Base64.encodeToString(credentials.toByteArray(), Base64.NO_WRAP)
headers["Authorization"] = auth
body = MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("usuario", binding.etUsername.text.toString())
.addFormDataPart("password", binding.etPwd.text.toString())
.build()
Log.d("okhttp", "createParameters: ")
}
And I am simply calling it like this
viewModel.login(body, headers)
Api is giving response but it is going in failure case. I am suspecting that body parameters are not being sent in request as in error it is saying related to username and password.
Below is the OkHttp code which works
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("usuario","FELIPEG")
.addFormDataPart("password","Fel10**11$$")
.build();
Request request = new Request.Builder()
.url("http://200.6.231.237:11000/gasolinera/v1/login")
.method("POST", body)
.addHeader("db", "P")
.addHeader("latitud", "0")
.addHeader("longitud", "0")
.addHeader("apiKey", "a9f1b3fd3d5a62782f24d2d00afe4532")
.addHeader("Authorization", "Basic Y2VudHJvOlNhbHVkMTAxMS4=")
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
I can't find the exact issue with retrofit.

Volley to Retrofit2 - How to do a String Request with Retrofit2?

I would like to migrate to Retrofit2 the following Volley string request.
This request retrieves a response body as String, which I parse myself.
fun updatePodcastEpisodesRQ( url: String) {
val feedReq = StringRequestUTF8(
Request.Method.GET,
url,
{ response: String? -> ...},
{ error: VolleyError ->...}
)
App.instance?.addToRequestQueue(feedReq, TAG_JSON_REQUEST1)
}
Please note that the URL can be any address, as a result there is no baseUrl as defined in Retrofit.Builder() when doing JSON request for example.
Is it possible to do such a simple request with Retrofit2 ?
In fact, okhttp3 fulfilled all my needs. I migrated from Volley to okhttp3.
private val client = OkHttpClient()
suspend fun getFeed(url: String): String {
val request = Request.Builder()
.url(url)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful)
throw IOException("Error occurred - code:${response.code} message=${response.message}")
if (response.body == null)
throw IOException("Error occurred - null body")
return response.body!!.string()
}
}

How can I get data from response body?

I need to get "status" value from my response. I tried JSONObject but it gave that java.lang.reflect.InvocationTargetException error in the code below. I need that because I make some process with status value like start new activity etc. How can I get this?
private fun doReq(){
val client = OkHttpClient().newBuilder()
.build()
val mediaType = "application/json;charset=utf-8".toMediaTypeOrNull()
val body: RequestBody = jsonSended.toRequestBody(mediaType)
val request: Request = Request.Builder()
.url("https://apiapiapi/auth")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "$authValue")
.addHeader("x-iyzi-rnd", "$randomString")
.addHeader("cache-control", "no-cache")
.build()
val response = client.newCall(request).execute()
println(response.body?.string()) // I CAN GET RESPONSE BODY
var json = JSONObject(response.body.toString())
var status = json.getString("status") // HERE NOT WORKING...
println(status)
}
In the response when server return failure : {"status":"failure","errorCode":"12","errorMessage":"invalid","locale":"tr","systemTime":1610022545347,"conversationId":"123412341234"}
If server return valid my response is very very long but it also have status so I can get that status value and do something with that. Is that correct way to do it? I need advice.
Use response.response or make request in try catch block statement, it will solve the problem
Something like this
private fun doReq(){
try {
var errorResponce: ErrorResponce? = null
val client = OkHttpClient().newBuilder()
.build()
val mediaType = "application/json;charset=utf-8".toMediaTypeOrNull()
val body: RequestBody = jsonSended.toRequestBody(mediaType)
val request: Request = Request.Builder()
.url("https://apiapiapi/auth")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "$authValue")
.addHeader("x-iyzi-rnd", "$randomString")
.addHeader("cache-control", "no-cache")
.build()
val response = client.newCall(request).execute()
println(response.body?.string()) // I CAN GET RESPONSE BODY
if (response.errorBody() != null) {
errorResponce = conversorDeErro.convert(response.errorBody()!!)
}
}
catch (e: IOException) {
println(e);
}
finally {
return errorResponce;
}
}
You should read response.body?.string() exactly once and store the result.
val response = client.newCall(request).execute()
println(response.body?.string()) // This permanently consumes the output, you should store the result
var json = JSONObject(response.body.toString()) // toString() is not the response body, it is a debug representation of the response body
var status = json.getString("status")

how to post request message pack with okhttp3

I'd like to set MIME type to "application/x-msgpack" but the type of MultipartBody should be MediaType so the app crashs.
How do I make a request?
val media = "multipart/form-data".toMediaTypeOrNull()
val boundary = System.currentTimeMillis().toString()
val file = MoshiPack().jsonToMsgpack("sample_file").readByteArray()
val requestBody: RequestBody = MultipartBody.Builder(boundary).setType("application/x-msgpack".toMediaTypeOrNull()!!)
.addFormDataPart("file", "fileName", file.toRequestBody(media, 0, file.size))
.build()
val request = Request.Builder()
.header("Content-Type", "application/json; charset=utf-8;multipart/form-data")
.url(requestUrl)
.post(paramData)
.post(requestBody)
.build()
okHttpClient.newCall(request)
implementation "com.squareup.okhttp3:okhttp:4.6.0"
You should only call post once per request you are building. Leave out the header("Content-Type", ...) call as it conflicts as well.
See https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/PostMultipart.java
So something like
var requestBody: RequestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(
"file", "fileName",
file.toRequestBody("application/x-msgpack".toMediaType())
)
.build()
var request: Request = Request.Builder()
.header("Authorization", "Client-ID XXXX")
.url("https://api.imgur.com/3/image")
.post(requestBody)
.build()

Categories

Resources