Upload Image with Json using Multipart - android

I've tried different approach but still getting stream was reset: NO_ERROR response from onFailure() using Retrofit.
What is the correct way to implement this kind of setup?
This is what my APIService looks like:
#Multipart
#POST(CREATE_STUDENT_RECORD)
Call<CreateStudentResult> createStudentRecord(#Header(PARAM_TOKEN) String token, #Part("studentlist") RequestBody studentList,
#Part MultipartBody.Part image, #Part("type") RequestBody type);
And this is my API Call:
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), APIConstants.capturedImage);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("image", APIConstants.capturedImage.getName(), requestBody);
RequestBody type = RequestBody.create(
MediaType.parse("text/plain"),
"Students");
String studentList = new Gson().toJson(APIConstants.studentRecord);
RequestBody students = RequestBody.create(
MediaType.parse("text/plain"),
studentList);

The image section isn't quite correct. You are sending a file of type "image/jpeg", so instead of:
RequestBody requestBody = RequestBody.create(
MediaType.parse("multipart/form-data"),
APIConstants.capturedImage
);
MultipartBody.Part filePart = MultipartBody.Part.createFormData(
"image",
APIConstants.capturedImage.getName(),
requestBody
);
You want:
RequestBody requestBody = RequestBody.create(
MediaType.parse("image/jpeg"),
APIConstants.capturedImage
);
MultipartBody.Part filePart = MultipartBody.Part.createFormData(
"image",
APIConstants.capturedImage.getName(),
requestBody);

Related

How can upload image to server with Retrofit on Android

In my application, I want to upload image to the server and for this, I used Retrofit2.
I write the below codes, but after upload the image shows me a server error!
This error is: Media field is empty, please fill this!
This error is from my server and says to me the media field is empty!
My API codes:
#Multipart
#POST("/media")
fun uploadImage(
#Header(AUTHORIZATION) auth: String, #Header(ACCEPT) accept: String, #Header(CONTENT_TYPE) contentType: String,
#PartMap map: LinkedHashMap<String, RequestBody>
): Single<Response<ResponseModelUploadImage>>
My Activity codes:
var requestBody: RequestBody
var body: MultipartBody.Part
val mapRequestBody = LinkedHashMap<String, RequestBody>()
Log.e("filePath",uploadNaturalImageFile.toString())
requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), uploadNaturalImageFile);
mapRequestBody.put("media\"; media=\"" + uploadNaturalImageFile.name, requestBody);
presenter.callUploadImage(userToken, APPLICATION_JSON, APPLICATION_JSON, mapRequestBody)
But when upload this image with Postman, everything is OK and doesn't have any problem!
Postman request image:
UPDATE : I see my log and show me name=media, but server again media is empty!
My logcat messages:
D/OkHttp: Content-Disposition: form-data; name="media"; filename="JPEG_20201108_1623315560915977415445829.jpg"
Why show me this error? how can I fix it?
in your RetrofitService.java
#Multipart
#POST("/app/uploadFile.do")
Call<JsonObject> uploadFile(#PartMap() LinkedHashMap<String, RequestBody> partMap, #Part List<MultipartBody.Part> names);
and in your activity,
public static void fileUpload (File file) {
Log.d(TAG, "file===" + file.getName());
RequestBody requestBody;
MultipartBody.Part body;
LinkedHashMap<String, RequestBody> mapRequestBody = new LinkedHashMap<String, RequestBody>();
List<MultipartBody.Part> arrBody = new ArrayList<>();
requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
mapRequestBody.put("file\"; filename=\"" + file.getName(), requestBody);
mapRequestBody.put("test", RequestBody.create(MediaType.parse("text/plain"), "gogogogogogogog"));
body = MultipartBody.Part.createFormData("fileName", file.getName(), requestBody);
arrBody.add(body);
Call<JsonObject> call = RetrofitImg.getInstance().getService().uploadFile(mapRequestBody, arrBody);
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (response.body() != null) {
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.e(TAG + "Err", t.getMessage());
}
});
}
UPDATA : I found other example
#POST("my/files/photo/")
Call<FileUploadResponse> uploadPhoto(#Header("Content-Type") String contentType,
#Header("Authorization") String auth,
#Body MultipartBody body);
and
ApiClient.ApiInterface client = ApiClient.getClient();
File file = new File(getPathFromUri(fileUri));
RequestBody fileBody = RequestBody.create(MediaType.parse(getContentResolver().getType(fileUri)), file);
MultipartBody body = new MultipartBody.Builder().addFormDataPart("file-type", "profile")
.addFormDataPart("photo", "image.png", fileBody)
.build();
client.uploadPhoto("multipart/form-data; boundary=" + body.boundary(),
PrefManager.getInstance().getToken(), body);

Convert OkHttp's Form Data (Android) to Axios(React Native)'s Form Data

I'm recreating a project that was originally designed for Native Android to use React Native. There is an endpoint that is responsible to send a image using Form Data. I tried to convert the OkHttp3's Form Data to Axios's Form Data and I'm getting an error from backend saying that the request fields doesn't match.
My Code so far:
- Native Android(original app):
public RequestResponse<Boolean> functionApi(#NonNull String id, String imageExtension, #NonNull byte[] imageData, #NonNull String anotherData) throws ServerErrorException, IOException, AuthenticationException {
String path = "route/" + id;
Pair<String, String> contentTypeHeader = new Pair<>("Content-Type", "multipart/form-data");
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("anotherData", anotherData)
.addFormDataPart("imageData", id + "." + imageExtension, RequestBody.create(MediaType.parse("image/png"), imageData))
.build();
Response response = MyHttpClient.execute(path, "POST", requestBody, contentTypeHeader);
String body = response.body().string();
RequestResponse<Boolean> r = responseBodyToObject(body, RequestResponse.class);
r.setBody(r.getStatus() != RequestResponse.ERROR);
return r;
}
React Native(new app) version:
export const functionApi = async(id,imageExtension,imageData,anotherData)=>{
try{
let formData = new FormData()
formData.append('anotherData',anotherData)
formData.append('imageData',`data:image/${imageExtension};base64,${imageData}`,`${id}.${imageExtension}`)
//imageData here i tried to use a base64's string
let res = await axios({
url:`${URL_SERVER}/route/${id}`,
method:'POST',
headers:{
'Content-Type':"multipart/form-data"
},
data:formData
})
return res['data']
}catch(err){
return getErrorMessage(err)
}
}
I got a solution that finally worked for me:
export const functionApi = async(id,imageExtension,imageData,anotherData)=>{
try{
let formData = new FormData()
formData.append('anotherData',anotherData)
formData.append('imageData',{
uri: imageData['uri'],
type: 'image/jpg',
name: `${id}.${imageExtension}`,
})
let res = await axios({
url:`${URL_SERVER}/route/${id}`,
method:'POST',
headers:{
'Content-Type':'multipart/form-data'
},
data:formData
})
return res['data']
}catch(err){
return getErrorMessage(err)
}
}

upload image with Chopper

How to upload an image to the server with chopper library? I tried the search on google but, I couldn't manage to get one.
What I have tried is
Function handle creating the chopper client
static ApiService create(String accessToken) {
final client = ChopperClient(
baseUrl: 'http://192.168.43.125:8000/api',
services: [
_$ApiService(),
],
converter: JsonConverter(),
interceptors: [
HeadersInterceptor({
"Content-Type": "application/x-www-form-urlencoded",
'Authorization': 'Bearer $accessToken',
'Accept': 'application/json',
}),
HttpLoggingInterceptor()
]);
return _$ApiService(client);}
API
#Post(path: '/inspectionStore',)
#multipart
Future<Response> storeInspection(
#Part("field") String field, #PartFile("file") http.MultipartFile file);
Code that do the work
File actualFile = photoSection.postImage[0];
http.MultipartFile file = await http.MultipartFile.fromPath('file', actualFile.path,contentType: MediaType('image', 'jpg'));
var response = await Provider.of<ApiService>(context).storeInspection('some name',file);
This is what the server retrieve (Laravel Log file)
How can I get a proper data that can be used?
I know it's a little late but this could save someone. So, you need to provide the path to your image as string
#multipart
Future<Response> storeInspection(
#Part("field") String field, #PartFile("file") String file);
then
File actualFile = photoSection.postImage[0];
var response = await Provider.of<ApiService>(context).storeInspection('some name',file.path);

sending file to server by okhttp

I have this node.js code in my server side app:
app.post('/upload',function (req,resp) {
console.log(req);
var email=req.headers['email']
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null,'uploads/')
},
filename: function (req, file, cb) {
cb(null,"asdsad"+".jpg")
}
})
var upload = multer({ storage: storage }).single('propic')
upload(req, resp, function (err) {
if (err) {
throw err
}
resp.setHeader('Content-Type', 'application/json');
resp.send({status:true})
})
})
I want to send a bitmap in client side (Android) to server.
I used the okhttp library and I want to create form-data.
How can I do that?
You must send File to your server instead of bitmap and must use POST method to handle the request to Server side.
and write this codes to send your file into the server:
public class UploadService {
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
public void uploadImage(File image, String imageName) throws IOException {
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file", imageName, RequestBody.create(MEDIA_TYPE_PNG, image))
.build();
Request request = new Request.Builder().url("http://localhost:8080/v1/upload")
.post(requestBody).build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
}
}

Retrofit 2 posting image and other data

Hello everyone I want to post image and other data through Retrofit2 please guide me where I am lacking in my code
#Multipart
#POST(HttpConstants.FILEUPLOADJSON1)
Call<Result>uploadImage(#Part MultipartBody.Part file,#Query("stdID")int stdID);
php part
$stdID=$_POST['stdID'];
$file_path = "profile_images/";
$file_path = $file_path . basename( $_FILES['uploaded_file']['name']);
$actualpath="http://myservices.96.lt/$file_path";
$sql = "UPDATE testuser SET profile_photo = '".$actualpath."' WHERE user_id = '".$stdID."'";
if(mysqli_query($conn,$sql))
{
if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path))
{
$result = array("result" => "success", "value" => $sql);
}
else
{
$result = array("result" => "error file transfer");
}
}else{
$result = array("result" => "error mysql");
}
echo json_encode($result);
use #Part instead of #Query in Multipart request
In your Retrofit api interface pass your parameter as followws.
#Multipart
#POST(HttpConstants.FILEUPLOADJSON1)
Call<Result>uploadImage(#Part MultipartBody.Part file, #Part("stdID") stdID);
I hope its work for you

Categories

Resources