问题
i'm trying to post encoded string of image to retrofit post method...after debugging i got very long string on debug of image chosen from gallery.....after submitting i can see long string encoded of image in debugger....in postman when i check i shows profile_pic: " "
that is null ...
need help
if i used endpoint like this im not getting crash:
@FormUrlEncoded
@POST("update")
fun useredit(
@Header("access_token") token: String,
@Field("first_name") first_name:String,
@Field("last_name") last_name:String,
@Field("email") email:String,
@Field("dob") dob:String,
@Field("phone_no") phone_no: String,
@Field("profile_pic") profile_pic:String
):Call<LoginResponse>
response code:
profile = findViewById<View>(R.id.profilepic) as ImageView
profile?.setOnClickListener(View.OnClickListener {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(intent, IMAGE)
})
editsubmit.setOnClickListener {
val first_name = firstname.text.toString().trim()
val last_name = lastname.text.toString().trim()
val email = emailregister.text.toString().trim()
val phone = phoneno.text.toString().trim()
val profile =convertToString()!!
val token: String =
SharedPrefManager.getInstance(
applicationContext
).user.access_token.toString()
RetrofitClient.instance.useredit(token,first_name,last_name,email,edittext1.text.toString(),phone,profile)
.enqueue(object : Callback<LoginResponse> {
override fun onFailure(call: Call<LoginResponse>, t: Throwable) {
Log.d("res", "" + t)
}
override fun onResponse(
call: Call<LoginResponse>,
response: Response<LoginResponse>
) {
var res = response
Log.d("response check ", "" + response.body()?.status.toString())
if (res.body()?.status==200) {
Toast.makeText(
applicationContext,
res.body()?.message,
Toast.LENGTH_LONG
).show()
Log.d("kjsfgxhufb",response.body()?.status.toString())
}
else
{
try {
val jObjError =
JSONObject(response.errorBody()!!.string())
Toast.makeText(
applicationContext,
jObjError.getString("message")+jObjError.getString("user_msg"),
Toast.LENGTH_LONG
).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, e.message, Toast.LENGTH_LONG).show()
Log.e("errorrr",e.message)
}
}
}
})
}
}
private fun convertToString(): String? {
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap?.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream)
val imgByte: ByteArray = byteArrayOutputStream.toByteArray()
return android.util.Base64.encodeToString(imgByte, android.util.Base64.NO_WRAP )
}
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == IMAGE && resultCode == Activity.RESULT_OK && data != null) {
val path: Uri? = data.data
try {
bitmap = MediaStore.Images.Media.getBitmap(contentResolver, path)
profile?.setImageBitmap(bitmap)
} catch (e: IOException) {
e.printStackTrace()
}
}
}
im seeing long string on debugger but not on postman
Later i tried this-->
my endpoint:
@Multipart
@POST("update")
fun useredit(
@Header("access_token") token: String,
@Part("first_name") first_name:String,
@Part("last_name") last_name:String,
@Part("email") email:String,
@Part("dob") dob:String,
@Part("phone_no") phone_no: String,
@Part ("profile_pic")profile_pic: MultipartBody.Part?
):Call<LoginResponse>
activity response code:-
profile?.setOnClickListener(View.OnClickListener {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(intent, IMAGE)
})
editsubmit.setOnClickListener {
val first_name = firstname.text.toString().trim()
val last_name = lastname.text.toString().trim()
val email = emailregister.text.toString().trim()
val phone = phoneno.text.toString().trim()
val profile =convertToString()!!
val token: String =
SharedPrefManager.getInstance(
applicationContext
).user.access_token.toString()
val requestFile: RequestBody =
RequestBody.create(MediaType.parse("image/jpeg"), profile)
val body: MultipartBody.Part =
MultipartBody.Part.createFormData("image", "image.jpg", requestFile)
RetrofitClient.instance.useredit(token,first_name,last_name,email,edittext1.text.toString(),phone,body)
.enqueue(object : Callback<LoginResponse> {
override fun onFailure(call: Call<LoginResponse>, t: Throwable) {
Log.d("res", "" + t)
}
override fun onResponse(
call: Call<LoginResponse>,
response: Response<LoginResponse>
) {
var res = response
Log.d("response check ", "" + response.body()?.status.toString())
if (res.body()?.status==200) {
Toast.makeText(
applicationContext,
res.body()?.message,
Toast.LENGTH_LONG
).show()
Log.d("kjsfgxhufb",response.body()?.status.toString())
}
else
{
try {
val jObjError =
JSONObject(response.errorBody()!!.string())
Toast.makeText(
applicationContext,
jObjError.getString("message")+jObjError.getString("user_msg"),
Toast.LENGTH_LONG
).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, e.message, Toast.LENGTH_LONG).show()
Log.e("errorrr",e.message)
}
}
}
})
}
}
private fun convertToString(): String? {
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap?.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream)
val imgByte: ByteArray = byteArrayOutputStream.toByteArray()
return android.util.Base64.encodeToString(imgByte, android.util.Base64.NO_WRAP )
}
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == IMAGE && resultCode == Activity.RESULT_OK && data != null) {
val path: Uri? = data.data
try {
bitmap = MediaStore.Images.Media.getBitmap(contentResolver, path)
profile?.setImageBitmap(bitmap)
} catch (e: IOException) {
e.printStackTrace()
}
}
}
}
well im getting crash from above code-->java.lang.IllegalArgumentException: @Part parameters using the MultipartBody.Part must not include a part name in the annotation. (parameter #7)
回答1:
Can you try to change something like below since all you are sending string so multipart file won't be ideal. just send it using request body let's see how server responds.
@Multipart
@POST("update")
fun useredit(
@Header("access_token") token: String,
@PartMap Map<String, RequestBody> partMap
):Call<LoginResponse>
and wherever you are calling do like this.
// create a map of data to pass along
RequestBody first_name = RequestBody.create(MediaType.parse("text/plain"),"your name here");
RequestBody last_name = RequestBody.create(MediaType.parse("text/plain"),"your last name here");
RequestBody email = RequestBody.create(MediaType.parse("text/plain"),"your email here");
RequestBody dob = RequestBody.create(MediaType.parse("text/plain"),"your dob here");
RequestBody phone_no = RequestBody.create(MediaType.parse("text/plain"),"your phone no here");
RequestBody profile_pic = RequestBody.create(MediaType.parse("text/plain"),"your picture base64 string here");
Map<String, RequestBody> map = new HashMap<>();
map.put("first_name", first_name);
map.put("last_name", last_name);
map.put("email", email);
map.put("dob", dob);
map.put("phone_no", phone_no);
map.put("profile_pic", profile_pic);
and then pass it to the calling function
RetrofitClient.instance.useredit(token, map)//some code follows
Edit:
also need to send the image base64 in correct format like
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ.........
or convert it to base64 encoding by using following method.
private fun convertToString(): String? {
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap?.compress(Bitmap.CompressFormat. JPEG, 100, byteArrayOutputStream)
val imgByte: ByteArray = byteArrayOutputStream.toByteArray()
return android.util.Base64.encodeToString(imgByte, android.util.Base64.NO_WRAP )
}
change your map from java to kotlin implementation as shown below in the code
val map: MutableMap<String, RequestBody> = HashMap()
map["first_name"] = first_name
map["last_name"] = last_name
map["email"] = email
map["dob"] = dob
map["phone_no"] = phone_no
map["profile_pic"] = profile_pic
来源:https://stackoverflow.com/questions/63149093/how-do-i-post-long-encoded-string-of-base64-image-to-server-using-retrofit