2009-07-13 21 views
13

(gelöst - siehe unten Kommentar)HttpURLConnection auf Android scheitern

ich eine Klasse, die eine mehrteilige Datei-Upload implementiert. Der Code funktioniert auf jedem Java-Client, auf dem ich ihn ausprobiert habe, mit Ausnahme von Android, und es ist der einzige HTTP-Anforderungscode in meiner Android-App, der mit meinem Backend-Dienst nicht gut spielt.

Die Verbindung responseCode ist "-1", also geht hier etwas ziemlich Schreckliches vor sich. Im Apache-Zugriff oder in den Fehlerprotokollen werden keine Einträge angezeigt. Es scheint, als würde die Anfrage nie von der Android-Plattform entfernt werden. Der Code wird direkt durch die Verbindung geschrieben, hängt aber an der Verbindung ab, läutet aus und kehrt dann zurück. Das Verhalten ist für echtes Telefon und Emulator gleich.

Kennt jemand irgendwelche Fehler, auf die man bei der Veröffentlichung einer mehrteiligen Datei in Android achten muss?

ich die Klasse unter (kleinere hygienische Mods gemacht) bin auch so können Sie sehen, was ich bis zu

bin
import java.io.ByteArrayOutputStream; 
import java.io.DataOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 

public class GeoPictureUploader 
{ 
    static String serviceDomain = "http://staging.abaqus.net"; 
    static String postUrl = serviceDomain + "/geo/upl/wupload/pictures"; 
    static String CRLF = "\r\n"; 
    static String twoHyphens = "--"; 
    static String boundary = "*****mgd*****"; 

    private String pictureFileName = null; 
    private String name = null; 
    private String password = null; 
    private DataOutputStream dataStream = null; 

    enum ReturnCode { noPicture, unknown, http201, http400, http401, http403, http404, http500}; 

    public GeoPictureUploader(String name, String password) 
    { 
     this.name = name; 
     this.password = password; 
    } 

    public static void setServiceDomain(String domainName) 
    { 
     serviceDomain = domainName; 
    } 

    public static String getServiceDomain() 
    { 
     return serviceDomain; 
    } 

    public ReturnCode uploadPicture(String pictureFileName) 
    { 
     this.pictureFileName = pictureFileName; 
     File uploadFile = new File(pictureFileName); 

     if (uploadFile.exists()) 
      try 
      { 
       FileInputStream fileInputStream = new FileInputStream(uploadFile); 
       URL connectURL = new URL(postUrl); 
       HttpURLConnection conn = (HttpURLConnection)connectURL.openConnection(); 

       conn.setDoInput(true); 
       conn.setDoOutput(true); 
       conn.setUseCaches(false); 
       conn.setRequestMethod("POST"); 

       conn.setRequestProperty("User-Agent", "myGeodiary-V1"); 
       conn.setRequestProperty("Connection","Keep-Alive"); 
       conn.setRequestProperty("Content-Type","multipart/form-data;boundary="+boundary); 

       conn.connect(); 

       dataStream = new DataOutputStream(conn.getOutputStream()); 

       writeFormField("login", name); 
       writeFormField("password", password); 
       writeFileField("photo1", pictureFileName, "image/jpg", fileInputStream); 

       // final closing boundary line 
       dataStream.writeBytes(twoHyphens + boundary + twoHyphens + CRLF); 

       fileInputStream.close(); 
       dataStream.flush(); 
       dataStream.close(); 
       dataStream = null; 

       String response = getResponse(conn); 
       int responseCode = conn.getResponseCode(); 

       if (response.contains("uploaded successfully")) 
        return ReturnCode.http201; 
       else 
        // for now assume bad name/password 
        return ReturnCode.http401; 
      } 
      catch (MalformedURLException mue) { 
       // Log.e(Tag, "error: " + mue.getMessage(), mue); 
       System.out.println("GeoPictureUploader.uploadPicture: Malformed URL: " + mue.getMessage()); 
       return ReturnCode.http400; 
      } 
      catch (IOException ioe) { 
       // Log.e(Tag, "error: " + ioe.getMessage(), ioe); 
       System.out.println("GeoPictureUploader.uploadPicture: IOE: " + ioe.getMessage()); 
       return ReturnCode.http500; 
      } 
      catch (Exception e) { 
       // Log.e(Tag, "error: " + ioe.getMessage(), ioe); 
       System.out.println("GeoPictureUploader.uploadPicture: unknown: " + e.getMessage()); 
       return ReturnCode.unknown; 
      } 
     else 
     { 
      return ReturnCode.noPicture; 
     } 
    } 

    /** 
    * @param conn 
    * @return 
    */ 
    private String getResponse(HttpURLConnection conn) 
    { 
     try 
     { 
      DataInputStream dis = new DataInputStream(conn.getInputStream()); 
      byte []  data = new byte[1024]; 
      int    len = dis.read(data, 0, 1024); 

      dis.close(); 
      int responseCode = conn.getResponseCode(); 

      if (len > 0) 
       return new String(data, 0, len); 
      else 
       return ""; 
     } 
     catch(Exception e) 
     { 
      System.out.println("GeoPictureUploader: biffed it getting HTTPResponse"); 
      //Log.e(TAG, "GeoPictureUploader: biffed it getting HTTPResponse"); 
      return ""; 
     } 
    } 

    /** 
    * this mode of reading response no good either 
    */ 
    private String getResponseOrig(HttpURLConnection conn) 
    { 
     InputStream is = null; 
     try 
     { 
      is = conn.getInputStream(); 
      // scoop up the reply from the server 
      int ch; 
      StringBuffer sb = new StringBuffer(); 
      while((ch = is.read()) != -1) { 
       sb.append((char)ch); 
      } 
      return sb.toString(); // TODO Auto-generated method stub 
     } 
     catch(Exception e) 
     { 
      System.out.println("GeoPictureUploader: biffed it getting HTTPResponse"); 
      //Log.e(TAG, "GeoPictureUploader: biffed it getting HTTPResponse"); 
     } 
     finally 
     { 
      try { 
      if (is != null) 
       is.close(); 
      } catch (Exception e) {} 
     } 

     return ""; 
    } 

    /** 
    * write one form field to dataSream 
    * @param fieldName 
    * @param fieldValue 
    */ 
    private void writeFormField(String fieldName, String fieldValue) 
    { 
     try 
     { 
      dataStream.writeBytes(twoHyphens + boundary + CRLF);  
      dataStream.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\"" + CRLF); 
      dataStream.writeBytes(CRLF); 
      dataStream.writeBytes(fieldValue); 
      dataStream.writeBytes(CRLF); 
     } 
     catch(Exception e) 
     { 
      System.out.println("GeoPictureUploader.writeFormField: got: " + e.getMessage()); 
      //Log.e(TAG, "GeoPictureUploader.writeFormField: got: " + e.getMessage()); 
     } 
    } 

    /** 
    * write one file field to dataSream 
    * @param fieldName - name of file field 
    * @param fieldValue - file name 
    * @param type - mime type 
    * @param fileInputStream - stream of bytes that get sent up 
    */ 
    private void writeFileField(
     String fieldName, 
     String fieldValue, 
     String type, 
     FileInputStream fis) 
    { 
     try 
     { 
      // opening boundary line 
      dataStream.writeBytes(twoHyphens + boundary + CRLF);  
      dataStream.writeBytes("Content-Disposition: form-data; name=\"" 
            + fieldName 
            + "\";filename=\"" 
            + fieldValue 
            + "\"" 
            + CRLF); 
      dataStream.writeBytes("Content-Type: " + type + CRLF); 
      dataStream.writeBytes(CRLF); 

      // create a buffer of maximum size 
      int bytesAvailable = fis.available(); 
      int maxBufferSize = 1024; 
      int bufferSize = Math.min(bytesAvailable, maxBufferSize); 
      byte[] buffer = new byte[bufferSize]; 
      // read file and write it into form... 
      int bytesRead = fis.read(buffer, 0, bufferSize); 
      while (bytesRead > 0) 
      { 
       dataStream.write(buffer, 0, bufferSize); 
       bytesAvailable = fis.available(); 
       bufferSize = Math.min(bytesAvailable, maxBufferSize); 
       bytesRead = fis.read(buffer, 0, bufferSize); 
      } 

      // closing CRLF 
      dataStream.writeBytes(CRLF); 
     } 
     catch(Exception e) 
     { 
      System.out.println("GeoPictureUploader.writeFormField: got: " + e.getMessage()); 
      //Log.e(TAG, "GeoPictureUploader.writeFormField: got: " + e.getMessage()); 
     } 
    } 


    /** 
    * @param args 
    */ 
    public static void main(String[] args) 
    { 
     if (args.length >= 0) 
     { 
      GeoPictureUploader gpu = new GeoPictureUploader("john", "notmyrealpassword"); 
      String picName = args[0]; 

      ReturnCode rc = gpu.uploadPicture(picName); 
      System.out.printf("done"); 
     } 
    } 

} 
+0

Nach vielen Stunden Debugging, stellt sich heraus, um einen Fehler in unserem Router zu sein, die aus irgendeinem Grund oder eine andere auf einer abgehenden Rundfahrt hängt wieder in unsere Inszenierung Server, wenn die Nachricht über einige k Bytes ist. Ich hatte auf einem Handy entwickelt, das drahtlose Netzwerkverbindung verwendet und natürlich verwendet der Emulator das Netzwerk auch. Sobald wir unseren Produktionsserver ins Visier genommen hatten, funktionierte es sofort. Cellular ist auch gut. – jottos

+3

Jeder bitte fühlen Sie sich frei, diese Android Multipart/Form-Daten-Klassen zu verwenden. Es funktioniert wie ein Champion. Und wird leicht zu einer generischen multipart/form-data-Klasse verallgemeinert. Cleanup Hinweis auf den Code - Sie können die Methoden getResponse() zugunsten der HttpURLConnection-Methode conn.getResponseMethod(), und natürlich die conn.getResponseCode(), um den richtigen HTTP-Server-Code – jottos

Antwort

2

Sie das Internet Erlaubnis gesetzt haben? Ich würde sicherstellen, dass einfach Gets (Verwenden Sie die HTTPUrl google holen) vor dem Versuch, Post zu debuggen.

+0

ja, die Anwendung zu entfernen tut ziemlich viele Http - alles erfolgreich – jottos

0

HI Ich habe Datei hochladen mit der gleichen HttpURLConnection gemacht. ich bin in der Lage, Dateien bis zu 25 MB auf erholsame Dienste hochzuladen. einen Blick könnte dies für Sie hilfreich sein: link

Verwandte Themen