我想知道Java中是否有任何标准API来验证给定的URL? 我想检查URL字符串是否正确,即给定协议是否有效,然后检查是否可以建立连接。
我尝试使用HttpURLConnection,提供URL并连接到它。我的要求的第一部分似乎已经完成,但是当我尝试执行HttpURLConnection.connect()时,会抛出'java.net.ConnectException:Connection refused'异常。
这可能是因为代理设置?我尝试为代理设置系统属性但没有成功。
让我知道我做错了什么。
答案 0 :(得分:135)
为了社区的利益,因为这个帖子在Google上搜索时是最重要的 “ url validator java ”
捕获异常代价很高,应尽可能避免。如果您只想验证String是否是有效的URL,则可以使用UrlValidator项目中的Apache Commons Validator类。
例如:
String[] schemes = {"http","https"}; // DEFAULT schemes = "http", "https", "ftp"
UrlValidator urlValidator = new UrlValidator(schemes);
if (urlValidator.isValid("ftp://foo.bar.com/")) {
System.out.println("URL is valid");
} else {
System.out.println("URL is invalid");
}
答案 1 :(得分:36)
您需要同时创建URL
对象和URLConnection
对象。以下代码将测试URL的格式以及是否可以建立连接:
try {
URL url = new URL("http://www.yoursite.com/");
URLConnection conn = url.openConnection();
conn.connect();
} catch (MalformedURLException e) {
// the URL is not in a valid form
} catch (IOException e) {
// the connection couldn't be established
}
答案 2 :(得分:29)
java.net.URL
类实际上并不是验证URL的好方法。在构建期间,所有格式错误的网址上都会{strong> 。在MalformedURLException
上捕获IOException
也不会验证网址,只是告诉是否可以建立连接。
考虑这段代码:
java.net.URL#openConnection().connect()
..不会抛出任何例外。
我建议使用一些使用无上下文语法实现的验证API,或者在非常简化的验证中使用正则表达式。但是我需要有人为此建议一个优质或标准的API,我最近才开始自己搜索它。
注意强>
有人建议将 try {
new URL("http://.com");
new URL("http://com.");
new URL("http:// ");
new URL("ftp://::::@example.com");
} catch (MalformedURLException malformedURLException) {
malformedURLException.printStackTrace();
}
与异常URL#toURI()
的处理相结合可以促进对URL的验证。但是,这种方法只能抓住上面一个非常简单的案例。
结论是没有标准的java URL解析器来验证URL。
答案 3 :(得分:11)
使用 only 标准API,将字符串传递给URL
对象,然后将其转换为URI
对象。这将根据RFC2396标准准确地确定URL的有效性。
示例:
public boolean isValidURL(String url) {
URL u = null;
try {
u = new URL(url);
} catch (MalformedURLException e) {
return false;
}
try {
u.toURI();
} catch (URISyntaxException e) {
return false;
}
return true;
}
答案 4 :(得分:8)
在android:
上使用android.webkit.URLUtil
URLUtil.isValidUrl(URL_STRING);
注意:它只是检查URL的初始方案,而不是整个URL是有效的。
答案 5 :(得分:4)
有一种方法可以严格按照Java标准执行URL验证,而无需使用第三方库:
boolean isValidURL(String url) {
try {
new URI(url).parseServerAuthority();
return true;
} catch (URISyntaxException e) {
return false;
}
}
URI
的构造函数检查url
是否为有效URI,对parseServerAuthority
的调用确保它是URL(绝对或相对)而不是URN。
答案 6 :(得分:2)
重要的是要指出URL对象同时处理验证和连接。然后,只有在 sun.net.www.protocol 中提供了处理程序的协议才被授权( file , ftp , gopher , http , https , jar , mailto < / em>, netdoc )是有效的。例如,尝试使用 ldap 协议创建一个新URL:
new URL("ldap://myhost:389")
您将获得java.net.MalformedURLException: unknown protocol: ldap
。
您需要实现自己的处理程序并通过URL.setURLStreamHandlerFactory()
进行注册。如果您只想验证URL语法,那么相当难以理解,正则表达式似乎是一种更简单的解决方案。
答案 7 :(得分:1)
您确定使用正确的代理作为系统属性吗?
此外,如果您使用的是1.5或1.6,则可以将java.net.Proxy实例传递给openConnection()方法。这是更优雅的imo:
//Proxy instance, proxy ip = 10.0.0.1 with port 8080
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("10.0.0.1", 8080));
conn = new URL(urlString).openConnection(proxy);
答案 8 :(得分:0)
我认为最好的响应来自用户@ b1nary.atr0phy。不知何故,我建议将b1nay.atr0phy响应中的方法与正则表达式结合使用,以涵盖所有可能的情况。
public static final URL validateURL(String url, Logger logger) {
URL u = null;
try {
Pattern regex = Pattern.compile("(?i)^(?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))\\.?)(?::\\d{2,5})?(?:[/?#]\\S*)?$");
Matcher matcher = regex.matcher(url);
if(!matcher.find()) {
throw new URISyntaxException(url, "La url no está formada correctamente.");
}
u = new URL(url);
u.toURI();
} catch (MalformedURLException e) {
logger.error("La url no está formada correctamente.");
} catch (URISyntaxException e) {
logger.error("La url no está formada correctamente.");
}
return u;
}
答案 9 :(得分:-1)
感谢。按照NickDK的建议通过代理打开URL连接正常。
//Proxy instance, proxy ip = 10.0.0.1 with port 8080
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("10.0.0.1", 8080));
conn = new URL(urlString).openConnection(proxy);
然而,系统属性不像我之前提到的那样有效。
再次感谢。
此致 科亚