How to Use Okhttp to Upload a File

how to use okhttp to upload a file?

Note: this answer is for okhttp 1.x/2.x. For 3.x, see this other answer.

The class Multipart from mimecraft encapsulates the whole HTTP body and can handle regular fields like so:

Multipart m = new Multipart.Builder()
.type(Multipart.Type.FORM)
.addPart(new Part.Builder()
.body("value")
.contentDisposition("form-data; name=\"non_file_field\"")
.build())
.addPart(new Part.Builder()
.contentType("text/csv")
.body(aFile)
.contentDisposition("form-data; name=\"file_field\"; filename=\"file1\"")
.build())
.build();

Take a look at examples of multipart/form-data encoding to get a sense of how you need to construct the parts.

Once you have a Multipart object, all that's left to do is specify the right Content-Type header and pass on the body bytes to the request.

Since you seem to be working with the v2.0 of the OkHttp API, which I don't have experience with, this is just guess code:

// You'll probably need to change the MediaType to use the Content-Type
// from the multipart object
Request.Body body = Request.Body.create(
MediaType.parse(m.getHeaders().get("Content-Type")),
out.toByteArray());

For OkHttp 1.5.4, here is a stripped down code I'm using which is adapted from a sample snippet:

OkHttpClient client = new OkHttpClient();
OutputStream out = null;
try {
URL url = new URL("http://www.example.com");
HttpURLConnection connection = client.open(url);
for (Map.Entry<String, String> entry : multipart.getHeaders().entrySet()) {
connection.addRequestProperty(entry.getKey(), entry.getValue());
}
connection.setRequestMethod("POST");
// Write the request.
out = connection.getOutputStream();
multipart.writeBodyTo(out);
out.close();

// Read the response.
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Unexpected HTTP response: "
+ connection.getResponseCode() + " " + connection.getResponseMessage());
}
} finally {
// Clean up.
try {
if (out != null) out.close();
} catch (Exception e) {
}
}

Uploading File with okhttp 3.9.0 to REST is giving Error code=422, message=Uprocessable Entity

I had a simple error in my test-id ... it works now ... :)

WRONG:
.addFormDataPart("FK_Person", "1d64b9cc-d405-47c4-9adb-ef276c391ae0&")

OK:
.addFormDataPart("FK_Person", "1d64b9cc-d405-47c4-9adb-ef276c391ae0")

How I can upload photos by Uri instead of File in Android Q using okhttp

That was solved after issuing a comment: InputStreamRequestBody.

https://github.com/square/okhttp/issues/3585#issuecomment-327319196

Multipart file upload using okhttp generated by postman

I found a way to multipart file upload by Ion.

Ion.with(context).load(url).setHeader("x-access-token", token)
.setMultipartParameter("x-access-token", token)
.setMultipartContentType("multipart/form-data")
.setMultipartFile("image", "image/jpeg", file)
.asString().withResponse().setCallback(new FutureCallback<Response<String>>() {
@Override
public void onCompleted(Exception e, Response<String> result) {
if (result != null)
onSuccess(result.getResult(), result.getHeaders().code());
}
});

Rest API:
Sample Image

Sample Image

Image upload using okHttp

You need to Use

new MultipartBody.Builder()

Instead of

new MultipartBuilder()

Its working

Uploading a large file in multipart using OkHttp

From the OkHttp Recipes page, this code uploads an image to Imgur:

private static final String IMGUR_CLIENT_ID = "...";
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

private final OkHttpClient client = new OkHttpClient();

public void run() throws Exception {
// Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"title\""),
RequestBody.create(null, "Square Logo"))
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"image\""),
RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
.build();

Request request = new Request.Builder()
.header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
.url("https://api.imgur.com/3/image")
.post(requestBody)
.build();

Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

System.out.println(response.body().string());
}

You'll need to adapt this to S3, but the classes you need should be the same.

File uploading on a PHP server using OkHttp, error?

To provide all deatails and what the problem was originally.

First of all everything works now.

The original issue ocurred when the image path provided was completly wrong, this was provided by the user inputting , however Glide could easily display it, so i did display it, then got the drawable convert it to bitmap and then byte[] and finally save the image by using FileOutStream to a cache created (cache is cleaned on the onStop() funstion), finally just use this.getCachedir() to grap the image path.

Build the Multipart.Builder, and .addFormDataPart("fileToUpload", result + ".png",
RequestBody.create(MEDIA_TYPE_PNG, new File(imagePath)))

This way The PHP server can get "fileToUpload" and store it, also the PHP file requires a directory to store the images, this case being the "images/", for that pre-create that directory so the PHP file recognizes it and stores it in.

For anyone that wants to use the same library and try to upload an image use the following code

For Java:

    public String postImage (String imagePath) {

result = ""+ System.currentTimeMillis();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("fileToUpload", result + ".png",
RequestBody.create(MEDIA_TYPE_PNG, new File(imagePath)))
.build();

Request request = new Request.Builder()
.url("http://192.168.0.17/addImage.php")
.post(requestBody)
.build();

client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
result = response.body().string();
}
}
});
return "http://192.168.0.17/uploads/"+result;
}

The PHP Server side:

    <?php

if ($_SERVER['REQUEST_METHOD']=='POST') {
$target_dir = "images/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
echo "File is not an image.";
$uploadOk = 0;
}
}?>

Remember to set the Permissions on your Android App, and set the php.ini to allow file uploads.

Android - how to upload video in chunks using OkHTTP?

You can create a custom RequestBody which streams the data. You will have to take some care: it may be reused multiple times because OkHttp may decide to retry the request. Make sure you can re-open the InputStream from the start each time.

ContentResolver contentResolver = context.getContentResolver();
final String contentType = contentResolver.getType(videoUri);
final AssetFileDescriptor fd = contentResolver.openAssetFileDescriptor(videoUri, "r");
if (fd == null) {
throw new FileNotFoundException("could not open file descriptor");
}
RequestBody videoFile = new RequestBody() {
@Override public long contentLength() { return fd.getDeclaredLength(); }
@Override public MediaType contentType() { return MediaType.parse(contentType); }
@Override public void writeTo(BufferedSink sink) throws IOException {
try (InputStream is = fd.createInputStream()) {
sink.writeAll(Okio.buffer(Okio.source(is)));
}
}
};
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", "fname", videoFile)
.build();
Request request = new Request.Builder()
.url(uploadURL)
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Call call, IOException e) {
try {
fd.close();
} catch (IOException ex) {
e.addSuppressed(ex);
}
Log.e(TAG, "failed", e);
}
@Override public void onResponse(Call call, Response response) throws IOException {
fd.close();
}
});

File upload through okhttp3

So I am answering this question myself.

So I am firstly opening an outputstream to a temporary file.

imageTempUploadfile=new File(Environment.getExternalStorageDirectory()+"/inpaint/");
if(!imageTempUploadfile.exists())
imageTempUploadfile.mkdirs();
imageTempUploadfile2 = new File(Environment.getExternalStorageDirectory() + "/inpaint/"+"file"+".docx");
OutputStream outputTempFileStream = new FileOutputStream(imageTempUploadfile2);

The extension depends upon the mime type.You can find the mime type by

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);

if(resultCode==RESULT_OK && requestCode==0){
Log.d("uri data",""+data.getData());

String mimetype = context.getContentResolver().getType(data.getData());

selectedFileUri = data.getData();

Now to read from the file and write its contents in the temporary file

selectedFileInputStream = getContentResolver().openInputStream(selectedFileUri);

Now to write into the file

try {
try {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;

while ((read = selectedFileInputStream.read(buffer)) != -1) {
outputTempFileStream.write(buffer, 0, read);
}
outputTempFileStream.flush();
} finally {
outputTempFileStream.close();
}
} catch (Exception e) {
e.printStackTrace(); // handle exception, define IOException and others
}

And finally

MultipartUtility multipart = new MultipartUtility(urlLeaveFormApply, charset);
multipart.addFilePart("data[User][user_picture]", imageTempUploadfile2);

At the end after success

imageTempUploadfile2.delete();


Related Topics



Leave a reply



Submit