Vlad Vlad - 6 months ago 66
Node.js Question

Upload image with Java MultipartEntity to Node.js server using express and multer

I'm trying to upload an image from an Android application using a custom

MultipartEntity
which also updates a
ProgressDialog
(that also being my reason for using the deprecated
MultipartEntity
).

Relevant Java code:

File file = new File(imgPath);

HttpPost post = new HttpPost("http://" + SERVER + "/upload");

MultipartEntity entity = new MyMultipartEntity(new MyMultipartEntity.ProgressListener()
{
public void transferred(long num)
{
publishProgress((int) ((num / (float) totalSize) * 100));
Log.d("DEBUG", num + " - " + totalSize);
}
});
ContentBody cbFile = new FileBody(file, "image/jpeg");
entity.addPart("source", cbFile);

totalSize = entity.getContentLength();

post.setEntity(entity);

HttpResponse response = client.execute(post);
int statusCode = response.getStatusLine().getStatusCode();

if(statusCode == HttpStatus.SC_OK){
String fullRes = EntityUtils.toString(response.getEntity());
Log.d("DEBUG", fullRes);

} else {
Log.d("DEBUG", "HTTP Fail, Response Code: " + statusCode);
}


Node.js server file:

var fs = require('fs');

var express = require('express');
var app = express();

var multer = require('multer');
var upload = multer(
{
limits: {
fieldNameSize: 999999999,
fieldSize: 999999999
},
dest: 'uploads/' }
);

app.get('/', function(req, res){
res.send(
'<form action="/upload" method="post" enctype="multipart/form-data">'+
'<input type="file" name="source">'+
'<input type="submit" value="Upload">'+
'</form>'
);
});

app.post('/upload', upload.any(), function(req, res){

console.log(req.files);

var tmp_path = req.files[0].path;

var target_path = 'uploads/' + req.files[0].originalname;

var src = fs.createReadStream(tmp_path);
var dest = fs.createWriteStream(target_path);
src.pipe(dest);
src.on('end', function() { res.send("ok"); });
src.on('error', function(err) { res.send({error: "upload failed"}); });
});

app.get('/info', function(req, res){
console.log(__dirname);
res.send("image upload server: post /upload");
});

app.listen(8080);
console.log('started server on localhost...');


I've also tried using the
upload.single()
approach (which works through the form) but that requires the name of the field which I'm not sure how/if I can add to the Java multipart entity object.

What I'm currently getting is an empty
files
array on the request and a
source
variable on the request
body
containing what seems like the raw data of the image, so basically it looks like multer isn't doing anything at all. What am I missing?

Thank you!

Answer

I ended up using the Android Ion library - https://github.com/koush/ion

Java code:

Ion.with(context)
            .load("http://" + SERVER + ":8080/upload")
            .progressDialog(pd)
            .setMultipartParameter("name", "source")
            .setMultipartFile("image", "image/jpeg", new File(imgPath))
            .asJsonObject()
            .setCallback(new FutureCallback<JsonObject>() {
                @Override
                public void onCompleted(Exception e, JsonObject result) {

                    //do stuff with result
                }
            });

The server code remained unchanged.