Java HttpURLConnection - “https://”与“http://”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18918662/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HttpURLConnection - "https://" vs. "http://"
提问by Jason Hu
I'm trying to get the favicon of the url the user enters, for example
例如,我正在尝试获取用户输入的 url 的图标
_url = "google.com";
I use HttpUrlConnection to get the Bitmap of the favicon from the /favicon.ico
extension from the host url.
我使用 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;
However, since the user probably won't specify http://
or https://
, I would have to add it myself. The problem I'm having is that, if I add http://
in front of the url, everything would work fine, but for https://
, some sites would return the favicon, others would just give me null. How do I find out which page uses https
? Should I just add http://
for every case? Are there any websites that restricts to strictly https
and would return null for using http
?
但是,由于用户可能不会指定http://
或https://
,因此我必须自己添加它。我遇到的问题是,如果我http://
在 url 前面添加,一切都会正常工作,但是对于https://
,某些站点会返回 favicon,而其他站点只会给我 null。我如何找出哪个页面使用https
?我应该http://
为每个案例添加吗?是否有任何网站严格限制https
使用并且会返回 null http
?
采纳答案by hooknc
Unless you use user2558882's ideaor there is some other tool out in the wild that will just get a websites favicon for you, you're going to have to check both the http and https urls. There is no other way to do this. It is part of the difficulty of using the web.
除非您使用 user2558882 的想法,或者有一些其他工具可以为您获取网站图标,否则您将不得不检查 http 和 https 网址。没有其他方法可以做到这一点。这是使用网络的困难的一部分。
Perhaps looking at your code differently and breaking down what you're trying to do into smaller more manageable parts would be a bit better?
也许以不同的方式看待您的代码并将您尝试做的事情分解成更小的更易于管理的部分会更好一些?
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, being concerned about one or two connections takes more time then writing the code to make two requests. I almost guarantee that google is making two requests as needed. And if it is good enough for google it is good enough for me.
顺便说一句,关注一两个连接比编写代码来发出两个请求需要更多的时间。我几乎可以保证 google 会根据需要提出两个请求。如果它对谷歌来说足够好,那么对我来说就足够了。
Finally, if you start to see that making two requests is really taking too much time, then do something about improving the performance.
最后,如果您开始发现发出两个请求确实花费了太多时间,那么请采取一些措施来提高性能。
回答by Sebastian Walla
How about checking if the website returns null or a favicon?
如何检查网站是否返回 null 或 favicon?
I hope this helps you
我希望这可以帮助你
回答by Vikram
Note: I am not sure how helpful my answer would be.
注意:我不确定我的回答会有多大帮助。
You can grab the favicon using google:
您可以使用谷歌获取图标:
http://www.google.com/s2/favicons?domain=stackoverflow.com
returns:
返回:
You don't have to specify http
or https
.
您不必指定http
或https
。
http://www.google.com/s2/favicons?domain=my.yorku.ca ===>> (https://my.yorku.ca)
returns:
返回:
But this is not the actual favicon that https://my.yorku.causes. So, I guess google returns a default one for sites that do not provide access their favicons.
但这不是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);
You can actually keep a copy of the default favicon and check if:
您实际上可以保留默认图标的副本并检查:
if (defaultBitmap.sameAs(favicon)) {
// favicon wasn't available
}
回答by DropAndTrap
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();
}
}
回答by hooknc
Another answer that is even 'easier'.
另一个甚至“更容易”的答案。
Just make the user enter the url (including protocol) for their favicon and validate that url returns a favicon. If not then display a validation error back to the end user.
只需让用户输入其收藏夹图标的 url(包括协议)并验证该 url 返回收藏夹图标。如果不是,则向最终用户显示验证错误。
Following agile principals, do the least amount of work and see what works. If the one plan doesn't work, then try something different.
遵循敏捷原则,做最少的工作,看看什么是有效的。如果一个计划不起作用,那么尝试不同的方法。
回答by Tapa Save
Try this when URL start with "https":
当 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)