Validating URL in Java

我想知道在 Java 中是否有任何标准 API 来验证给定的 URL? I want to check both if the URL string is right i.e. the given protocol is valid and then to check if a connection can be established.

我尝试使用 HttpURLConnection,提供 URL 并连接到它。我的需求的第一部分似乎已经完成,但是当我尝试执行 HttpURLConnection.connect ()时,‘ java.net。ConnectException: 引发“连接拒绝”异常。

这是因为代理设置的原因吗? 我试过为代理设置系统属性,但没有成功。

让我知道我做错了什么。

187776 次浏览

您确定使用了正确的代理作为系统属性吗?

同样,如果你使用1.5或1.6,你可以传递一个 java.net。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);

您需要同时创建一个 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
}

谢谢。按照 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);

然而,系统属性不能像我前面提到的那样工作。

Thanks again.

问候, 柯雅

指出 URL 对象同时处理验证和连接非常重要。然后,只有在 翻译: 奇芳校对: 奇芳中提供了处理程序的协议才被授权(文件, 其中,ftp 地鼠译注:Https罐子邮件Netdoc是有效的。例如,尝试使用 Idap协议创建一个新的 URL:

new URL("ldap://myhost:389")

You will get a java.net.MalformedURLException: unknown protocol: ldap.

You need to implement your own handler and register it through URL.setURLStreamHandlerFactory(). Quite overkill if you just want to validate the URL syntax, a regexp seems to be a simpler solution.

For the benefit of the community, since this thread is top on Google when searching for
网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器”“ 网址验证器


捕获异常代价高昂,应尽可能避免。如果只想验证 String 是否为有效 URL,可以使用 Apache Commons Validator 项目中的 UrlValidator类。

For example:

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 的好方法。在构建期间,MalformedURLException没有抛出在所有畸形 URL 上。在 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 为此,我只是最近才开始搜索它自己。

Note 有人建议,URL#toURI()与异常 java.net. URISyntaxException的处理相结合可以促进 URL 的验证。但是,这种方法只能捕获上述非常简单的情况之一。

结论是没有标准的 java URL 解析器来验证 URL。

使用 只有标准 API,将字符串传递给 URL对象,然后将其转换为 URI对象。这将根据 RFC2396标准准确地确定 URL 的有效性。

例如:

public boolean isValidURL(String url) {


try {
new URL(url).toURI();
} catch (MalformedURLException | URISyntaxException e) {
return false;
}


return true;
}

在 android 上使用 android.webkit.URLUtil:

URLUtil.isValidUrl(URL_STRING);

注意: 它只是检查 URL 的初始方案,并不是说整个 URL 都是有效的。

有一种方法可以严格按照 Java 中的标准执行 URL 验证,而无需求助于第三方库:

boolean isValidURL(String url) {
try {
new URI(url).parseServerAuthority();
return true;
} catch (URISyntaxException e) {
return false;
}
}

URI的构造函数检查 url是否是有效的 URI,对 parseServerAuthority的调用确保它是一个 URL (绝对或相对)而不是 URN。

我认为最好的回应来自用户@b1nary。萎缩。不管怎样,我建议将 b1nay.atrphy 响应的方法与正则表达式结合起来,以涵盖所有可能的情况。

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;


}

This is what I use to validate CDN urls (must start with https, but that's easy to customise). This will also not allow using IP addresses.

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();
}