2012-08-22 32 views
11

Tôi đang nhắm mục tiêu dịch vụ web REST từ Android 4.0 bằng cách sử dụng HttpsURLConnection. Điều này hoạt động tốt trừ khi tôi cố gắng POST điều gì đó. Đây là phần mã có liên quan:Làm cách nào để tắt chế độ phát trực tuyến chunked một cách rõ ràng cho các kết nối HTTP trong Android?

connection.setDoOutput(true); 
    connection.setChunkedStreamingMode(0); 

    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    serializeObjectToStream(out, object); 
    byte[] array = out.toByteArray(); 
    connection.getOutputStream().write(array, 0, array.length); 

này ném ngoại lệ sau đây:

java.net.HttpRetryException: Cannot retry streamed HTTP body 

Từ gỡ lỗi tôi nhận ra rằng dòng đầu ra tôi nhận được qua connection.getOuputStream() là loại ChunkedOutputStream và từ đào trong mã nguồn Androids Tôi thấy rằng nếu một yêu cầu cần phải được thử lại (vì bất kỳ lý do gì), nó sẽ xảy ra với ngoại lệ trên, vì nó chỉ ra rằng nó là không phải sử dụng một số RetryableOutputStream mà nó muốn ở đó.

Câu hỏi bây giờ là: Làm cách nào để làm cho HttpsURLConnection của tôi trở lại như một RetryableOutputStream, hay đúng hơn, làm thế nào tôi có thể ngăn chặn yêu cầu chunked mã hóa đúng cách? Tôi nghĩ tôi đã làm điều đó đã có setChunkedStreamingMode(0), nhưng dường như đây không phải là trường hợp ...

[sửa]

Không, việc thực hiện java.net.HTTPUrlConnection bỏ qua một chế độ trực tuyến từ 0 hoặc thấp hơn:

public void setChunkedStreamingMode(int chunkLength) { 
    [...] 
    if (chunkLength <= 0) { 
     this.chunkLength = HttpEngine.DEFAULT_CHUNK_LENGTH; 
    } else { 
     this.chunkLength = chunkLength; 
    } 
} 
+0

Trên một lưu ý liên quan: Tôi nghĩ lý do _why_ nó muốn một RetryableOutputStream ở tất cả là vì có được một sự bảo vệ cơ bản Auth cấu hình trên máy chủ REST và HttpURLConnectionImpl của Android dường như tự động thử lại yêu cầu khi nó nhận được câu trả lời 401 trái phép. –

Trả lời

12

Rất tiếc! Giải pháp không được gọi là setChunkedStreamingMode() (hoặc thậm chí setFixedStreamingMode()) từ mã máy khách! "-1" là giá trị mặc định nội bộ cho fixedLength và chunkedLength và không thể đặt phía máy khách, vì đặt giá trị thấp hơn hoặc bằng "0" cho phép mặc định là HttpEngine.DEFAULT_CHUNK_LENGTH (hoặc ném ngoại lệ trong trường hợp chế độ phát cố định).

2

Giải pháp là đặt tiêu đề Content-Length (có thể được đặt bởi phần tiếp theo này) và gọi setFixedLengthStreamingMode với độ dài phù hợp của thông báo POST bạn định gửi.

Hãy xem phần "chế độ trực tuyến" trong này SO FAQ:

Using java.net.URLConnection to fire and handle HTTP requests

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