HttpURLConnection - “https://”与“http://”

时间:2013-09-20 14:00:55

标签: java android http httpurlconnection favicon

我正在尝试获取用户输入的网址的图标,例如

_url = "google.com";

我使用HttpUrlConnection从主机网址的/favicon.ico扩展名中获取favicon的位图。

        String faviconString = Uri.parse(_url).getHost() + "/favicon.ico";
        URL faviconUrl = null;
        Bitmap favicon = null;
        try
        {
            faviconString = "http://" + faviconString;
            faviconUrl = new URL(faviconString);
            HttpURLConnection connection = (HttpURLConnection) faviconUrl.openConnection();
            connection.setDoInput(true);
            connection.connect();
            favicon = BitmapFactory.decodeStream(connection.getInputStream());
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return favicon;

但是,由于用户可能不会指定http://https://,因此我必须自行添加。我遇到的问题是,如果我在网址前添加http://,一切都会正常工作,但对于https://,有些网站会返回图标,其他网站只会给我null。如何找出哪个页面使用https?我应该为每个案例添加http://吗?是否有任何网站严格限制https并使用http返回null?

6 个答案:

答案 0 :(得分:4)

注意:我不确定我的回答会有多大帮助。

您可以使用google抓取favicon:

http://www.google.com/s2/favicons?domain=stackoverflow.com

返回:

enter image description here

您不必指定httphttps

 http://www.google.com/s2/favicons?domain=my.yorku.ca ===>> (https://my.yorku.ca)

返回:

enter image description here

但这不是https://my.yorku.ca使用的实际图标。所以,我猜谷歌会为那些不提供访问权限的网站返回默认值。

InputStream is = null;

String urlPrefix = "http://www.google.com/s2/favicons?domain=";

String _url = "google.com";

Bitmap favicon = null;

try {

    is = (InputStream) new URL(urlPrefix + _url).getContent();

} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

favicon = BitmapFactory.decodeStream(is);

您实际上可以保留默认图标的副本并检查是否:

if (defaultBitmap.sameAs(favicon)) {
    // favicon wasn't available
}

答案 1 :(得分:4)

除非您使用user2558882的idea或者还有一些其他工具可以为您获取网站图标,否则您将需要同时检查http和https网址。没有其他办法可以做到这一点。这是使用网络的难度的一部分。

或许以不同方式查看您的代码并将您尝试做的内容分解为更小的更易于管理的部分会更好一点?

public void getFavicon(String host) {

    URL httpUrl = this.getHttpUrl(host + "/favicon.ico");

    Bitmap favicon = this.getBitmap(httpUrl);

    if (favicon == null) {

        URL httpsUrl = this.getHttpsUrl(host + "/favicon.ico");

        favicon = this.getBitmap(httpsUrl);
    }

    if (favicon == null) {

        throw new FaviconMissingException("Unable to find favicon for host: " + host);
    }

    return favicon;
}

public URL getHttpUrl(String uri) throws MalformedURLException {

    // There are better ways of building a url then string concationation.
    return new URL("http://" + uri);
}

public URL getHttpsUrl(String uri) throws MalformedURLException {

    // There are better ways of building a url then string concationation.
    return new URL("https://" + uri);
}

public Bitmap getBitmap(URL url) {

    InputStream inputStream = getInputStream(url);

    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

    return bitmap
}

public InputStream getInputStream(URL url) {

    // Please use a real connection library like HTTPClient here!
    // HttpClient will handle timeouts, redirects, and things like that for you.
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setDoInput(true);
    connection.connect();

    return connection.getInputStream();
}
BTW,关注一个或两个连接需要花费更多时间,然后编写代码来发出两个请求。我几乎保证谷歌会根据需要提出两个请求。如果谷歌足够好对我来说已经足够了。

最后,如果你开始看到提出两个请求确实花费了太多时间,那么就做一些提高性能的事情。

答案 2 :(得分:3)

            URL url = new URL(downloadURL);
            HttpURLConnection urlCon = null;

            URL testUrlHttps = new URL(downloadURL);
            if (testUrlHttps.getProtocol().toLowerCase().equals("https"))
            {
                trustAllHosts();
                HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
                https.setHostnameVerifier(DO_NOT_VERYFY);
                urlCon = https;
            } else
            {
                urlCon = (HttpURLConnection) url.openConnection();
            }




add this method. May be it will help



   private static void trustAllHosts()
    {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
        {
            public java.security.cert.X509Certificate[] getAcceptedIssuers()
            {
                return new java.security.cert.X509Certificate[] {};
            }

            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
            {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
            {
            }
        } };

        // Install the all-trusting trust manager
        try
        {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

答案 3 :(得分:1)

检查网站是否返回null或者是favicon?

我希望这有助于你

答案 4 :(得分:1)

另一个答案甚至是“更容易”。

只需让用户为其favicon输入url(包括协议)并验证该url是否返回了favicon。如果没有,则将验证错误显示给最终用户。

遵循敏捷原则,做最少量的工作,看看哪些有效。如果一个计划不起作用,那么尝试不同的东西。

答案 5 :(得分:1)

当网址以“https”开头时尝试此操作:

              TrustManager[] trustAllCerts = new TrustManager[]
               {
                 new X509TrustManager()
                  {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers()  { return null; }
                    public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType)  {}
                    public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType)  {}
                  }
                 };
              try
                {
                  SSLContext sc = SSLContext.getInstance( "SSL"); // "TLS" "SSL"
                  sc.init( null, trustAllCerts, null);
                  HttpsURLConnection.setDefaultSSLSocketFactory( sc.getSocketFactory());
                  HttpsURLConnection.setDefaultHostnameVerifier( 
                   new HostnameVerifier() 
                    {
                      public boolean verify( String hostname, SSLSession session) { return true; }
                    } );
                }
               catch( Exception e)