Я пытаюсь получить ответ 206 с моего сервера с помощью Android.
Вот код.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { try { URL url = new URL("http://aviddapp.com/10mb.file"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestProperty("Range", "bytes=1-2"); urlConnection.connect(); System.out.println("Response Code: " + urlConnection.getResponseCode()); System.out.println("Content-Length: " + urlConnection.getContentLength()); Map<String, List<String>> map = urlConnection.getHeaderFields(); for (Map.Entry<String, List<String>> entry : map.entrySet()) { System.out.println("Key : " + entry.getKey() + " ,Value : " + entry.getValue()); } InputStream inputStream = urlConnection.getInputStream(); long size = 0; while(inputStream.read() != -1 ) size++; System.out.println("Downloaded Size: " + size); }catch(MalformedURLException mue) { mue.printStackTrace(); }catch(IOException ioe) { ioe.printStackTrace(); } return null; } }.execute(); }
Вот результат:
I/System.out: Respnse Code: 200 I/System.out: Content-Length: -1 I/System.out: Key : null ,Value : [HTTP/1.1 200 OK] I/System.out: Key : Accept-Ranges ,Value : [bytes] I/System.out: Key : Cache-Control ,Value : [max-age=604800, public] I/System.out: Key : Connection ,Value : [Keep-Alive] I/System.out: Key : Date ,Value : [Tue, 04 Oct 2016 07:45:22 GMT] I/System.out: Key : ETag ,Value : ["a00000-53e051f279680-gzip"] I/System.out: Key : Expires ,Value : [Tue, 11 Oct 2016 07:45:22 GMT] I/System.out: Key : Keep-Alive ,Value : [timeout=5, max=100] I/System.out: Key : Last-Modified ,Value : [Tue, 04 Oct 2016 07:36:42 GMT] I/System.out: Key : Server ,Value : [Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4] I/System.out: Key : Transfer-Encoding ,Value : [chunked] I/System.out: Key : Vary ,Value : [Accept-Encoding,User-Agent] I/System.out: Key : X-Android-Received-Millis ,Value : [1475567127403] I/System.out: Key : X-Android-Response-Source ,Value : [NETWORK 200] I/System.out: Key : X-Android-Sent-Millis ,Value : [1475567127183] I/System.out: Downloaded Size: 10485760
Теперь я делаю то же самое, это чистая java.
public static void main(String... args) { try { URL url = new URL("http://aviddapp.com/10mb.file"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestProperty("Range", "bytes=1-2"); urlConnection.connect(); System.out.println("Respnse Code: " + urlConnection.getResponseCode()); System.out.println("Content-Length: " + urlConnection.getContentLength()); Map<String, List<String>> map = urlConnection.getHeaderFields(); for (Map.Entry<String, List<String>> entry : map.entrySet()) { System.out.println("Key : " + entry.getKey() + " ,Value : " + entry.getValue()); } InputStream inputStream = urlConnection.getInputStream(); long size = 0; while(inputStream.read() != -1 ) size++; System.out.println("Downloaded Size: " + size); }catch(MalformedURLException mue) { mue.printStackTrace(); }catch(IOException ioe) { ioe.printStackTrace(); } }
Вот результат
Respnse Code: 206 Content-Length: 2 Key : Keep-Alive ,Value : [timeout=5, max=100] Key : null ,Value : [HTTP/1.1 206 Partial Content] Key : Server ,Value : [Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4] Key : Content-Range ,Value : [bytes 1-2/10485760] Key : Connection ,Value : [Keep-Alive] Key : Last-Modified ,Value : [Tue, 04 Oct 2016 07:36:42 GMT] Key : Date ,Value : [Tue, 04 Oct 2016 07:42:17 GMT] Key : Accept-Ranges ,Value : [bytes] Key : Cache-Control ,Value : [max-age=604800, public] Key : ETag ,Value : ["a00000-53e051f279680"] Key : Vary ,Value : [Accept-Encoding,User-Agent] Key : Expires ,Value : [Tue, 11 Oct 2016 07:42:17 GMT] Key : Content-Length ,Value : [2] Downloaded Size: 2
Как вы можете видеть, я получаю разные коды ответов в обоих случаях. Похоже, Android не пропускает Range
на сервер, может быть? Что тут происходит?
PS: Я получаю 206, если размер файла равен 1 МБ.
Я относительно уверен, что ошибка не в коде Android.
Похоже, сервер может поставлять ложные результаты.
Вы можете проверить сторонним инструментом (например, почтальон), чтобы определить заголовки, которые предоставляет веб-служба.
Мои результаты с помощью Postman. Как вы можете видеть, он доставляет HTTP 200
(не 206
). Это также не позволяет ограничить Content-Length
. Если сервер принадлежит вам, возможно, убедитесь, что он настроен правильно. Также проверьте свой код на других серверах.
Привет Могу ли вы попробовать этот кусок кода, кажется, я получаю HTTP 206
здесь.
new Thread() { @Override public void run() { try { URL url = new URL("http://aviddapp.com/10mb.file"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); // urlConnection.setRequestMethod("HEAD"); urlConnection.setRequestProperty("Accept-Encoding", ""); urlConnection.setRequestProperty("Range", "bytes=1-2"); urlConnection.connect(); System.out.println("Response Code: " + urlConnection.getResponseCode()); System.out.println("Content-Length: " + urlConnection.getContentLength()); Map<String, List<String>> map = urlConnection.getHeaderFields(); for (Map.Entry<String, List<String>> entry : map.entrySet()) { System.out.println("Key : " + entry.getKey() + " ,Value : " + entry.getValue()); } InputStream inputStream = urlConnection.getInputStream(); long size = 0; while (inputStream.read() != -1) size++; System.out.println("Downloaded Size: " + size); } catch (IOException ioe) { ioe.printStackTrace(); } } }.start();
Вам просто нужно добавить это в async-задачу.
Проверьте этот результат, комментируя эту строку.
urlConnection.setRequestProperty("Accept-Encoding", "");
Я не уверен, связано ли это с тем, что Content-Length
по умолчанию аннулируется по умолчанию. Посмотрите на приведенный ниже фрагмент кода из исходного кода, где говорится, что он делает сжатие gzip по умолчанию.
По умолчанию эта реализация
HttpURLConnection
требует, чтобы серверы использовали сжатие gzip и автоматически распаковывали данные для вызывающих пользователейgetInputStream()
. Заголовки ответа Content-Encoding и Content-Length в этом случае очищаются.
Можете ли вы попробовать отключить кэширование по умолчанию, используя приведенный ниже код, чтобы проверить, работает ли это?
urlConnection.setRequestProperty("Accept-Encoding", "identity");
PS: Извините за плохие формы. Использование мобильной версии SO.
Вы пробовали вот так:
urlConnection.setRequestProperty("Range", "bytes=1000-");