Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload a file with Android to Django web service

I'm working on an Android app that interfaces with a Django backend. I've deployed the webservice using mod_wsgi, and have many web service calls that work and have been tested, so I know everything SHOULD be working. All the other calls work fine. This is the method I call in Android to send the photo.

public static String uploadFile(String url, int server_id, String filepath) {
    try {
        client.getParams().setParameter("http.socket.timeout", 90000); // 90 second
        HttpPost post = new HttpPost(url);

        MultipartEntity mpEntity = new MultipartEntity();
        mpEntity.addPart("image", new FileBody(new File(filepath), "image/jpeg"));
        post.setEntity(mpEntity);
        post.addHeader("server_id", String.valueOf(server_id));

        HttpResponse response = Connector.client.execute(post);
        if (response.getStatusLine().getStatusCode() != 200) { return "false"; }
        return convertStreamToString(response.getEntity().getContent());
    } catch (Exception e) {
        if (Constants.DEBUG) e.printStackTrace();
        return "false";
    }
}

This is the method I'm using in my views.py file to receive and process the image:

@csrf_exempt
def incident_upload(request):
    if request.method == 'POST':
            server_id = request.POST['server_id']
            incident = get_object_or_404(Incident, pk=server_id)
            imagePath = '/Library/WebServer/program/uploads/' + str(int(time.time() * 1000)) + '.jpg'
            destination = open(imagePath, 'wb+')
            for chunk in request.FILES['image'].chunks():
                    destination.write(chunk)
            destination.close()
            incident.ImagePath = imagePath
            incident.save()
            return render_to_response('webservice/incident_read.html', {'incident': incident, 'device': incident.device})

When I try this method, I get the really helpful Apache error 500 Internal Server Error, and I have no clue what's going on. I know this method works because I can use a custom html page I wrote to hit the web service without Android and it works fine:

<html>
<body>
<form action="http://xxxxxxxxxxx.local/hermes/incident/upload/" enctype="multipart/form-data" method="post">
server_id: <input type="text" name="server_id" />
<br />
file: <input type="file" name="image" />
<br />
<input type="submit" value="send" />
</form>
</body>
</html>

So I think there has to be something wrong with how I'm formatting the call on the Android side. I'd provide an error log or stack trace but there aren't any. I'm looking at my apache error log and nothing shows up. Anyone have any advice?

EDIT: So I set up django logging and have been able to debug my upload method when I hit it from the phone. It seems it stops working when I say server_id = request.POST['server_id'], so somehow, that piece of data isn't getting set right when I make the request in the uploadFile method. Anyone see how I'm doing the request incorrectly?

like image 882
joshkendrick Avatar asked Dec 09 '11 14:12

joshkendrick


1 Answers

I figured out what I was doing wrong. After setting up django logging, I was able to see where it was crashing. It was crashing when I tried to retrieve the "server_id" variable. I ended up adding that variable to the multipart entity as a string body rather than setting it as a header.

like image 99
joshkendrick Avatar answered Nov 10 '22 19:11

joshkendrick