2009-07-13 59 views
13

(Giải Quyết - xem bình luận bên dưới)HttpURLConnection thất bại trên Android

Tôi có một lớp mà thực hiện một tập tin tải lên nhiều phần dữ liệu. Mã hoạt động trên mọi ứng dụng khách java mà tôi đã thử trên ngoại trừ Android và đó là mã yêu cầu HTTP duy nhất trong ứng dụng Android của tôi không hoạt động tốt với dịch vụ kết thúc của tôi.

Phản hồi kết nốiMode là "-1" vì vậy có điều gì đó khá khó chịu đang diễn ra ở đây. Không có mục nào hiển thị trong truy cập Apache hoặc nhật ký lỗi, có vẻ như yêu cầu không bao giờ làm cho nó tắt khỏi nền tảng Android. Mã được quyền thông qua kết nối ghi, nhưng treo trên kết nối đọc, thời gian ra và sau đó trả về. Hành vi giống nhau đối với điện thoại thực và trình mô phỏng.

Có ai biết về bất kỳ gotchas nào cần xem xét khi đăng một tệp nhiều phần trong Android không?

tôi bao gồm các lớp bên dưới (mods vệ sinh nhỏ thực hiện) để bạn có thể thấy những gì tôi đang lên đến

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

Sau nhiều giờ gỡ lỗi, hóa ra là lỗi trong bộ định tuyến của chúng tôi vì lý do nào đó hoặc lỗi khác đang treo trên chuyến đi khứ hồi trở lại giai đoạn của chúng tôi máy chủ khi thông báo vượt quá vài k byte. Tôi đã phát triển trên một chiếc điện thoại đang sử dụng kết nối mạng không dây và dĩ nhiên Emulator cũng sử dụng mạng này. Khi chúng tôi nhắm mục tiêu máy chủ sản xuất của mình, nó đã hoạt động ngay lập tức. Cellular cũng tốt. – jottos

+3

Mọi người vui lòng sử dụng các lớp dữ liệu đa dạng/hình thức Android này. Nó hoạt động như một nhà vô địch. Và dễ dàng được khái quát hóa thành một lớp đa dữ liệu/biểu mẫu dạng chung. Gợi ý dọn dẹp trên mã - bạn có thể xóa phương thức getResponse() có lợi cho phương pháp HttpURLConnection conn.getResponseMethod() và dĩ nhiên là conn.getResponseCode() để nhận mã máy chủ http thích hợp – jottos

Trả lời

2

Bạn đã thiết lập sự cho phép internet? Tôi sẽ đảm bảo Gets đơn giản (Sử dụng HTTPUrl để tìm nạp google) trước khi cố gắng gỡ lỗi bài đăng.

+0

có, ứng dụng có khá một vài Http được - tất cả đều thành công – jottos

0

HI tôi đã thực hiện tải lên tệp bằng cùng một HttpURLConnection. tôi có thể tải lên các tệp có dung lượng tối đa 25 mb cho các dịch vụ an toàn. có giao diện điều này có thể hữu ích cho bạn: link

Các vấn đề liên quan