2012-03-18 141 views
6

我想用android作为前端和django上传图片作为后端。Android-Django图片上传

模型

class Photo(models.Model): 
     title = models.CharField(max_length=255,blank=True) 
     photo = models.FileField(upload_to='photos') 
     description = models.TextField(blank=True) 
     uploaded = models.DateTimeField(auto_now_add=True) 
     modified = models.DateTimeField(auto_now=True) 

     class Meta: 
      db_table = 'media_photos' 

     def __unicode__(self): 
      return '%s' % self.title 

视图以URL URL(R '^照片/上传/ $', 'upload_photo'):

def upload_photo(request): 
form=PhotoForm(request.POST,request.FILES) 
if request.method=='POST': 
    if form.is_valid(): 
     image = request.FILES['photo'] 
     title1 ='' 
     new_image = Photo(title=title1,photo=image,description='') 
     new_image.save() 
     response_data=[{"success": "1"}] 
     return HttpResponse(simplejson.dumps(response_data), mimetype='application/json') 

我现在想从android访问此处的视图。 所以现在我的Android端代码上传图片:

 public void doFileUpload(String path){ 
     HttpURLConnection conn = null; 
     DataOutputStream dos = null; 
     DataInputStream inStream = null; 
     String lineEnd = "\r\n"; 
     int bytesRead, bytesAvailable, bufferSize; 
     byte[] buffer; 
     int maxBufferSize = 1*1024*1024; 
     String urlString = "http://"; // server ip 
     try 
     { 
     //------------------ CLIENT REQUEST 
     FileInputStream fileInputStream = new FileInputStream(new File(path)); 
     // open a URL connection to the Servlet 
     URL url = new URL(urlString); 
     // Open a HTTP connection to the URL 
     conn = (HttpURLConnection) url.openConnection(); 
     // Allow Inputs 
     conn.setDoInput(true); 
     // Allow Outputs 
     conn.setDoOutput(true); 
     // Don't use a cached copy. 
     conn.setUseCaches(false); 
     // Use a post method. 
     conn.setRequestMethod("POST"); 
     conn.setRequestProperty("Connection", "Keep-Alive"); 
     conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+" "); 
     dos = new DataOutputStream(conn.getOutputStream()); 
     dos.writeBytes(lineEnd); 
     dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + path + "\"" + lineEnd); 
     dos.writeBytes(lineEnd); 

     // create a buffer of maximum size 
     bytesAvailable = fileInputStream.available(); 
     bufferSize = Math.min(bytesAvailable, maxBufferSize); 
     buffer = new byte[bufferSize]; 

     // read file and write it into form... 
     bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
     while (bytesRead > 0) 
     { 
      dos.write(buffer, 0, bufferSize); 
      bytesAvailable = fileInputStream.available(); 
      bufferSize = Math.min(bytesAvailable, maxBufferSize); 
      bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
     } 

     // send multipart form data necesssary after file data... 
     dos.writeBytes(lineEnd); 
     dos.writeBytes(lineEnd); 

     // close streams 
     Log.e("Debug","File is written"); 
     fileInputStream.close(); 
     dos.flush(); 
     dos.close(); 
     } 
     catch (MalformedURLException ex) 
     { 
      Log.e("Debug", "error: " + ex.getMessage(), ex); 
     } 
     catch (IOException ioe) 
     { 
      Log.e("Debug", "error: " + ioe.getMessage(), ioe); 
     } 

     //------------------ read the SERVER RESPONSE 
     try { 
       inStream = new DataInputStream (conn.getInputStream()); 
       String str; 
       while ((str = inStream.readLine()) != null) 
       { 
        Log.e("Debug","Server Response "+str); 
       } 
       inStream.close(); 
     } 
     catch (IOException ioex){ 
      Log.e("Debug", "error: " + ioex.getMessage(), ioex); 
     } 
     } 
} 

,但它给我一个错误:

E/Debug(590): error: java.net.URISyntaxException: Authority expected at index 7: http:// 
+1

也许你应该添加一些真实的URL到'urlString =“http://”' – zapl 2012-03-18 14:23:20

+0

其实我已经添加了“private static String recordURL =”http://192.168.1.2/photos/upload/“;”这是调用这个上传功能。但它仍然给我上面给出的错误 – user1163236 2012-03-18 17:15:03

+0

你使用你定义的字符串吗? 'URL url = new URL(recordURL);' – zapl 2012-03-18 17:17:29

回答

2

应该urlString = "http://192.168.1.2/photos/upload";

不过,如果它不工作,你会得到一个不同的错误,我们可能需要这个错误来进一步回答。

此外,它看起来像你没有一个真正的边界字符串集,你没有正确使用它。

http://stunningco.de/2010/04/25/uploading-files-to-http-server-using-post-android-sdk/,请注意他是如何使用唯一的边界字符串,并将其写入输出流?

您应该开始将您的问题标记为已回答。当你这样做时,你会有更好的成功。

0

即使在克服了这些困难后,您也会遇到Django的要求,即您提供了一个带有POST参数的csrfmiddlewaretoken。我不明白你在Android设备上如何获得这些信息。通过设计该令牌可以防止从除Django前端(即,“模板”)以外的任何其他方面调用Django后端代码(即“视图”)。即它旨在阻止你正在做的事情。

您可以禁用特定视图的csrf功能 - 使用“@csrf_exempt”修饰器。然后你可以决定你是否关心安全性,找出你自己的替代品,以确定csrf的东西给你带来什么。或者,而不是从Android应用程序上传图片,编写一个Web应用程序上传图片,并让您的Django项目提供该Web应用程序。您的Android应用可以启动浏览器(作为意图)并将其指向该Web应用。这里有一些代码会这样做:https://simpleisbetterthancomplex.com/tutorial/2016/08/01/how-to-upload-files-with-django.html(它不会赢得任何选美比赛,但它确实有效。)