我无法将图像文件(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愿意处理的最大尺寸是多少?或者仅仅是为了将文件保存到磁盘而不是接收其内容?