从Android到Django的文件上传导致空的request.FILES字典

时间:2014-01-13 20:17:01

标签: java android python django http

我无法将图像文件(jpg格式)从Android设备上的SD卡上传到Django服务器。据我所知,我正在做两端的所有标准事情,并且相信我已经遵循了我在网上阅读的警告和警告(SO和其他方式)。

这是我在Android上做的事情(从AsyncTask调用它 - 未显示,但确认在我正在运行的程序中使用print语句):

public static boolean uploadFile(String path, String serverURL) {
    HttpClient client = new DefaultHttpClient();
    client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

    HttpPost        post   = new HttpPost( serverURL );
    MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
    entity.addPart( "file", new FileBody((new File(path)), "image/jpeg" ));
    post.setEntity( entity );
    try {
        HttpResponse response = client.execute(post);
        Log.d(LOG_TAG, response.getStatusLine().toString());
        String responseText = EntityUtils.toString( response.getEntity(), "UTF-8" );
        Log.d(LOG_TAG, responseText);
        return response.getStatusLine().getStatusCode() == 200;
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    client.getConnectionManager().shutdown();
    return false;
}

这是Django方面,在views.py中(我通过URL调用的是upload_photo):

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
import simplejson

from photos.models import Photo

def index(request):
    return HttpResponse("Hello, world. You're at the photos index.")

@csrf_exempt
def upload_photo(request):
    title1 ='test'
    new_image = Photo(title=title1, photo=request.FILES['file'], description='')
    new_image.save()
    response_data=[{"success": "1"}]
    #return HttpResponse(request.body) -- do this to see the raw packet format of the request, just as a sanity check. It returns the response shown in the next code section.
    return HttpResponse(simplejson.dumps(response_data), mimetype='application/json')

我有一个名为Photo的模型(在上面调用,但未显示),用于保存上传的图像文件。传递它的文件参数(request.FILES ['file'])虽然失败了,如下所示。

Java程序返回500错误,从Django的响应中打印以下回溯:

01-13 14:30:21.070: D/FileUpload(2049): HTTP/1.1 500 INTERNAL SERVER ERROR
01-13 14:30:21.070: D/FileUpload(2049): Traceback (most recent call last):
01-13 14:30:21.070: D/FileUpload(2049):   File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
01-13 14:30:21.070: D/FileUpload(2049):     response = callback(request, *callback_args, **callback_kwargs)
01-13 14:30:21.070: D/FileUpload(2049):   File "/usr/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 77, in wrapped_view
01-13 14:30:21.070: D/FileUpload(2049):     return view_func(*args, **kwargs)
01-13 14:30:21.070: D/FileUpload(2049):   File "/mit/eliasb/Scripts/django/me/server/photos/views.py", line 13, in upload_photo
01-13 14:30:21.070: D/FileUpload(2049):     new_image = Photo(title=title1, photo=request.FILES['file'], description='')
01-13 14:30:21.070: D/FileUpload(2049):   File "/usr/lib/python2.7/site-packages/django/utils/datastructures.py", line 258, in __getitem__
01-13 14:30:21.070: D/FileUpload(2049):     raise MultiValueDictKeyError("Key %r not found in %r" % (key, self))
01-13 14:30:21.070: D/FileUpload(2049): MultiValueDictKeyError: "Key 'file' not found in <MultiValueDict: {}>"

似乎文件字典是空的。这是为什么?


下面的附录。以上内容完整地描述了我的问题,但是我在这里参考了一些我尝试过的事情。

当我在Django视图中取消注释倒数第二行(打印原始请求数据)时,这是它发回的内容(一些HTTP头内容然后是大量的二进制JPEG数据)。 / p>

01-13 13:54:14.872: D/FileUpload(8930): --WZ4aemH--fFnroCDynihK_UAeUSUfzOUO3
01-13 13:54:14.872: D/FileUpload(8930): Content-Disposition: form-data; name="file"
01-13 13:54:14.872: D/FileUpload(8930): 
01-13 13:54:14.872: D/FileUpload(8930): ���ၱExif����MM��*��������
01-13 13:54:14.872: D/FileUpload(8930): ����������������������������������������(��������������2���������������������������������������1�������������i������������Ո%�����������������i������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������H������������H������2014:01:13 13:54:08��Google��Glass 1��Glass-1 XE12 947604����!�����������0220������������������������������������������������������������������������   �������������@�������������������������������"���������������'����������D�������
01-13 13:54:14.872: D/FileUpload(8930): ����������������������������
01-13 13:54:14.872: D/FileUpload(8930): ��������������
01-13 13:54:14.872: D/FileUpload(8930): ��������������������������������������ǒ������������������������������   ���������� �����
01-13 13:54:14.872: D/FileUpload(8930): ������������Ϣ������������ע������������ߣ���������������������������������������������������������������������������������������������������������������  �����������������
01-13 13:54:14.872: D/FileUpload(8930): �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������B��B@�������������d�������������������������d����������������������������
01-13 13:54:14.872: D/FileUpload(8930): �������������d������������������'������d�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������h����������������������������������������(���������������������������������������@|��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������H������������H����������    �JFIF������������BCEEFEEEEIFFJHKIJJIIJNKKJNLMOOMMMOMOONPOPRQSRPTRSRURSUVSTUVUVUUXVWWXWVYXXXZYYYXYZZY\[Z[\[[\\[]

很明显,服务器正在获取文件数据,而不是将其放入request.FILES字典中。我甚至尝试解析了包含文件内容字节的request.content部分,并将它们写入磁盘,但这只会产生一个无法打开的损坏的JPEG文件。

看起来我正在做的事与这个人做的非常相似:Upload a file with Android to Django web service

我遵循其他地方的建议,确保将我的表单编码为enctype =“multipart / form-data”(通过Apache HTTP API调用,以及使用参数HttpMultipartMode.BROWSER_COMPATIBLE而不是HttpMultipartMode.STRICT作为这里描述:http://www.radomirml.com/blog/2009/02/13/file-upload-with-httpcomponents-successor-of-commons-httpclient/ - 虽然对我来说他们也有同样的效果。)

我在这里尝试使用Apache的示例代码:http://hc.apache.org/httpcomponents-client-ga/httpmime/examples/org/apache/http/examples/entity/mime/ClientMultipartFormPost.java, 但我在这一行得到例外:CloseableHttpClient httpclient = HttpClients.createDefault();

01-13 14:50:54.251: E/AndroidRuntime(4448): FATAL EXCEPTION: AsyncTask #1
01-13 14:50:54.251: E/AndroidRuntime(4448): java.lang.RuntimeException: An error occured while executing doInBackground()
01-13 14:50:54.251: E/AndroidRuntime(4448):     at android.os.AsyncTask$3.done(AsyncTask.java:287)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:217)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at java.lang.Thread.run(Thread.java:856)
01-13 14:50:54.251: E/AndroidRuntime(4448): Caused by: java.lang.ExceptionInInitializerError
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$InternalConnectionFactory.<init>(PoolingHttpClientConnectionManager.java:487)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:147)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:136)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:112)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:727)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.client.HttpClients.createDefault(HttpClients.java:58)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at sethberg.glass.me.FileUpload.uploadFile(FileUpload.java:26)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at sethberg.glass.me.FileUploadTask.doInBackground(FileUploadTask.java:24)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at sethberg.glass.me.FileUploadTask.doInBackground(FileUploadTask.java:1)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at android.os.AsyncTask$2.call(AsyncTask.java:273)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-13 14:50:54.251: E/AndroidRuntime(4448):     ... 5 more
01-13 14:50:54.251: E/AndroidRuntime(4448): Caused by: java.lang.ExceptionInInitializerError
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:72)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:84)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<clinit>(ManagedHttpClientConnectionFactory.java:59)
01-13 14:50:54.251: E/AndroidRuntime(4448):     ... 16 more
01-13 14:50:54.251: E/AndroidRuntime(4448): Caused by: java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:56)
01-13 14:50:54.251: E/AndroidRuntime(4448):     at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<clinit>(DefaultHttpRequestWriterFactory.java:46)
01-13 14:50:54.251: E/AndroidRuntime(4448):     ... 19 more

这里有指针吗?这方面的Python和Java都很简单。 Java代码似乎更让我怀疑,因为它更长,并且在Django方面实际上没有任何改变 - 只需抓住request.FILES中的内容......文件大小小于2.5 MB(它接近1 MB )据我所知,Django愿意处理的最大尺寸是多少?或者仅仅是为了将文件保存到磁盘而不是接收其内容?

0 个答案:

没有答案