10

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

_url = "google.com";

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

        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://or https://,所以我必须自己添加它。我遇到的问题是,如果我http://在 url 前面添加,一切都会正常工作,但是对于https://某些网站会返回 favicon,其他网站只会给我 null。如何找出使用哪个页面https?我应该http://为每个案例添加吗?是否有任何网站严格限制https并返回 null 使用http

4

6 回答 6

6

除非您使用 user2558882 的想法,或者有一些其他工具可以为您获取网站图标,否则您将不得不检查 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();
}

顺便说一句,关心一两个连接比编写代码发出两个请求需要更多时间。我几乎可以保证谷歌会根据需要发出两个请求。如果它对谷歌来说足够好,那对我来说就足够了。

最后,如果您开始发现发出两个请求确实花费了太多时间,那么请采取一些措施来提高性能。

于 2013-09-27T22:54:32.560 回答
4

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

您可以使用 google 获取 favicon:

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

返回:

在此处输入图像描述

您不必指定httphttps

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

返回:

在此处输入图像描述

但这不是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);

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

if (defaultBitmap.sameAs(favicon)) {
    // favicon wasn't available
}
于 2013-09-24T03:08:33.700 回答
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();
        }
    }
于 2013-09-24T10:32:06.290 回答
1

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

我希望这可以帮助你

于 2013-09-23T18:41:20.520 回答
1

当 URL 以“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)
于 2013-09-30T11:53:48.593 回答
1

另一个更“简单”的答案。

只需让用户输入他们的 favicon 的 url(包括协议)并验证 url 返回一个 favicon。如果没有,则向最终用户显示验证错误。

遵循敏捷原则,做最少的工作,看看什么是有效的。如果一个计划不起作用,那么尝试不同的方法。

于 2013-09-29T16:17:32.297 回答