我想知道在Java中是否有任何标准API可以验证给定的URL?
我想检查URL字符串是否正确,即所提供的协议是否有效,并检查是否可以建立连接。
我尝试使用HttpURLConnection,提供URL并连接到它。 我的第一个要求似乎已经满足了,但是当我尝试执行HttpURLConnection.connect()时,会抛出“java.net.ConnectException:连接被拒绝”的异常。
这可能是代理设置导致的吗?我尝试设置代理的系统属性,但没有成功。
请告诉我我做错了什么。
我想知道在Java中是否有任何标准API可以验证给定的URL?
我想检查URL字符串是否正确,即所提供的协议是否有效,并检查是否可以建立连接。
我尝试使用HttpURLConnection,提供URL并连接到它。 我的第一个要求似乎已经满足了,但是当我尝试执行HttpURLConnection.connect()时,会抛出“java.net.ConnectException:连接被拒绝”的异常。
这可能是代理设置导致的吗?我尝试设置代理的系统属性,但没有成功。
请告诉我我做错了什么。
为了造福社区,因为这个线程在搜索"url validator java"时是谷歌排名第一的
捕获异常是昂贵的,应该尽可能避免。如果你只想验证你的字符串是否为有效的 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");
}
java.net.URL
类实际上并不是一种好的验证URL的方式。在构建过程中,并不会对所有格式错误的URL引发MalformedURLException
异常。在java.net.URL#openConnection().connect()
上捕获IOException
也不能验证URL,只能告诉连接是否可以建立。
考虑以下代码:
try {
new URL("http://.com");
new URL("http://com.");
new URL("http:// ");
new URL("ftp://::::@example.com");
} catch (MalformedURLException malformedURLException) {
malformedURLException.printStackTrace();
}
......不会引发任何异常。
我建议使用一些基于上下文无关语法实现的验证API,或者在非常简化的验证中只使用正则表达式。然而,我需要有人提出一个更好或标准的API,因为我自己最近才开始搜索。
注意
有人建议结合处理异常java.net.URISyntaxException
的URL#toURI()
可以方便地验证URL。然而,该方法仅能捕获以上很简单的一种情况。
结论是,没有标准的Java URL解析器用于验证URL。
您需要创建一个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
}
仅使用标准API,将字符串传递给URL
对象,然后将其转换为URI
对象。这将根据RFC2396标准准确确定URL的有效性。
示例:
public boolean isValidURL(String url) {
try {
new URL(url).toURI();
} catch (MalformedURLException | URISyntaxException e) {
return false;
}
return true;
}
在Java中,有一种严格按照标准执行URL验证的方法,而不需要借助第三方库:
boolean isValidURL(String url) {
try {
new URI(url).parseServerAuthority();
return true;
} catch (URISyntaxException e) {
return false;
}
}
URI
的构造函数会检查 url
是否为有效的 URI,而调用 parseServerAuthority
确保它是一个 URL(绝对或相对),而不是 URN。URI
构造函数调用和parseServerAuthority
调用的组合会验证URL,而不仅仅是parseServerAuthority
。 - dened://
出现在主机后面,:
引入端口号,根据语法可以为空。//
是路径的一部分,具有空段,这也是有效的。
如果您在浏览器中输入此地址,它将尝试打开它(但很可能找不到名为 https
的服务器 ;))。 - dened在安卓系统上,可以使用 android.webkit.URLUtil
工具:
URLUtil.isValidUrl(URL_STRING);
重要的是指出URL对象处理验证和连接。然后,只有在sun.net.www.protocol中提供了处理程序的协议才被授权(文件,ftp,gopher,http,https,jar,mailto,netdoc)是有效的。例如,尝试使用LDAP协议创建新的URL:
new URL("ldap://myhost:389")
你会得到一个 java.net.MalformedURLException: unknown protocol: ldap
。
你需要实现自己的处理程序,并通过 URL.setURLStreamHandlerFactory()
注册它。如果你只想验证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);
这是我用来验证CDN网址的方法(必须以https开头,但很容易自定义)。这也不允许使用IP地址。
public static final boolean validateURL(String url) {
var regex = Pattern.compile("^[https:\\/\\/(www\\.)?a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)");
var matcher = regex.matcher(url);
return matcher.find();
}
我认为最好的回答来自用户@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;
}