首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >忽略Android中的HttpUrlConnection设置范围

忽略Android中的HttpUrlConnection设置范围
EN

Stack Overflow用户
提问于 2016-10-04 15:54:35
回答 4查看 2.5K关注 0票数 19

我正在尝试使用Android从我的服务器获取206响应。

这是代码。

代码语言:javascript
复制
@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();
}

下面是输出:

代码语言:javascript
复制
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

现在我在做同样的事情是纯

代码语言:javascript
复制
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();
    }
}

这里是输出的

代码语言:javascript
复制
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

如您所见,我在这两种情况下都得到了不同的响应代码。看起来安卓似乎没有把Range传给服务器?这是怎么回事?

PS:如果文件大小是1mb,我会得到206。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-10-11 18:55:49

我相对确定错误不在Android代码中。

看起来服务器可能正在提供虚假的结果。

您可以使用third party tool (such as Postman)进行检查,以确定web服务正在交付的标头。

我使用Postman得到的结果。正如您所看到的,它提供的是HTTP 200 (而不是206)。它也没有赢得一个有上限的Content-Length。如果服务器是您的,也许可以检查它是否配置正确。还要检查您的代码与其他服务器。

票数 6
EN

Stack Overflow用户

发布于 2016-10-11 22:08:19

嗨,你能试试这段代码吗,看起来我在这里得到了HTTP 206

代码语言:javascript
复制
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();

你只需要在异步任务中添加这个即可。

检查此结果,并在此行上/下注释。

代码语言:javascript
复制
urlConnection.setRequestProperty("Accept-Encoding", "");
票数 5
EN

Stack Overflow用户

发布于 2016-10-11 21:36:33

我不确定这是否与安卓默认清除Content-Length有关。看一下源代码中的以下代码片段,其中显示默认情况下执行gzip压缩。

https://android.googlesource.com/platform/libcore/+/2e317a02b5a8f9b319488ab9311521e8b4f87a0a/luni/src/main/java/java/net/HttpURLConnection.java

默认情况下,此HttpURLConnection实现请求服务器使用gzip压缩,并自动为getInputStream()调用者解压缩数据。在这种情况下,Content-Encoding和Content-Length响应头将被清除。

您是否可以尝试使用以下代码禁用默认缓存,以检查是否有效?

urlConnection.setRequestProperty("Accept-Encoding", "identity");

PS:为糟糕的格式道歉。使用SO的移动版本。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39847019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档