Étant donné une URL, je veux extraire le nom de domaine (il ne devrait pas inclure la partie 'www'). L'URL peut contenir http/https. Voici le code Java que j'ai écrit. Bien que cela semble fonctionner correctement, existe-t-il une meilleure approche ou existe-t-il des cas Edge qui pourraient échouer?.
public static String getDomainName(String url) throws MalformedURLException{
if(!url.startsWith("http") && !url.startsWith("https")){
url = "http://" + url;
}
URL netUrl = new URL(url);
String Host = netUrl.getHost();
if(Host.startsWith("www")){
Host = Host.substring("www".length()+1);
}
return Host;
}
Entrée: http://google.com/blah
Sortie: google.com
Si vous souhaitez analyser une URL, utilisez Java.net.URI
. Java.net.URL
a beaucoup de problèmes - sa méthode equals
effectue une recherche DNS, ce qui signifie que le code qui l'utilise peut être vulnérable aux attaques par déni de service lorsqu'il est utilisé avec des entrées non fiables.
"M. Gosling - pourquoi avez-vous rendre url égal à sucer?" explique un tel problème. Prenez l’habitude d’utiliser plutôt Java.net.URI
.
public static String getDomainName(String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost();
return domain.startsWith("www.") ? domain.substring(4) : domain;
}
devrait faire ce que vous voulez.
Bien que cela semble fonctionner correctement, existe-t-il une meilleure approche ou existe-t-il des cas Edge qui pourraient échouer?.
Votre code tel qu'écrit échoue pour les URL valides:
httpfoo/bar
- URL relative avec un composant de chemin qui commence par http
.HTTP://example.com/
- le protocole est insensible à la casse.//example.com/
- URL relative au protocole avec un hôtewww/foo
- une URL relative avec un composant de chemin qui commence par www
wwwexample.com
- nom de domaine qui ne commence pas par www.
mais commence par www
.Les URL hiérarchiques ont une grammaire complexe. Si vous essayez de lancer votre propre analyseur sans lire attentivement la RFC 3986, vous vous y tromperez probablement. Utilisez simplement celui qui est intégré aux bibliothèques principales.
Si vous avez vraiment besoin de gérer des entrées en désordre que Java.net.URI
rejette, voir RFC 3986 Annexe B:
Annexe B. Analyse d'une référence URI avec une expression régulière
Comme l'algorithme "first-match-wins" est identique à l'algorithme "glouton" La méthode d’homonymie utilisée par les expressions rationnelles POSIX, c’est naturel et banal d’utiliser une expression régulière pour analyser le potentiel de cinq composants d’une référence d’URI.
La ligne suivante est l'expression régulière permettant de décomposer un référence d'URI bien formée dans ses composants.
^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? 12 3 4 5 6 7 8 9
Les chiffres de la deuxième ligne ci-dessus servent uniquement à améliorer la lisibilité; ils indiquent les points de référence pour chaque sous-expression (c'est-à-dire, chaque parenthèse appariée).
import Java.net.*;
import Java.io.*;
public class ParseURL {
public static void main(String[] args) throws Exception {
URL aURL = new URL("http://example.com:80/docs/books/tutorial"
+ "/index.html?name=networking#DOWNLOADING");
System.out.println("protocol = " + aURL.getProtocol()); //http
System.out.println("authority = " + aURL.getAuthority()); //example.com:80
System.out.println("Host = " + aURL.getHost()); //example.com
System.out.println("port = " + aURL.getPort()); //80
System.out.println("path = " + aURL.getPath()); // /docs/books/tutorial/index.html
System.out.println("query = " + aURL.getQuery()); //name=networking
System.out.println("filename = " + aURL.getFile()); ///docs/books/tutorial/index.html?name=networking
System.out.println("ref = " + aURL.getRef()); //DOWNLOADING
}
}
Voici une ligne courte et simple utilisant InternetDomainName.topPrivateDomain()
en goyave: InternetDomainName.from(new URL(url).getHost()).topPrivateDomain().toString()
Étant donné http://www.google.com/blah
, cela vous donnera google.com
. Ou, étant donné http://www.google.co.mx
, il vous donnera google.co.mx
.
Comme Sa Qada a commenté dans une autre réponse à ce message , cette question a déjà été posée: Extrait le nom de domaine principal d'une url donnée . La meilleure réponse à cette question provient de Satya , qui suggère InternetDomainName.topPrivateDomain () de Guava.
public boolean isTopPrivateDomain ()
Indique si ce nom de domaine est composé de exactement un composant de sous-domaine suivi d'un suffixe public. Par exemple, renvoie vrai pour google.com et foo.co.uk, mais pas pour www.google.com ou co.uk.
Avertissement: Un résultat vrai de cette méthode n'implique pas que le domaine est au plus haut niveau qui est adressable en tant qu'hôte, autant que les suffixes publics sont également des hôtes adressables. Par exemple, le domaine bar.uk.com a un suffixe public de uk.com, donc il renverrait true à partir de cette méthode. Mais uk.com est lui-même un hôte adressable.
Cette méthode peut être utilisée pour déterminer si un domaine est probablement le niveau le plus élevé pour lequel les cookies peuvent être configurés, même si cela dépend sur les implémentations individuelles des navigateurs des contrôles de cookie. Voir RFC 2109 pour plus de détails.
En associant cela à URL.getHost()
, que le message original contient déjà, vous obtenez:
import com.google.common.net.InternetDomainName;
import Java.net.URL;
public class DomainNameMain {
public static void main(final String... args) throws Exception {
final String urlString = "http://www.google.com/blah";
final URL url = new URL(urlString);
final String Host = url.getHost();
final InternetDomainName name = InternetDomainName.from(Host).topPrivateDomain();
System.out.println(urlString);
System.out.println(Host);
System.out.println(name);
}
}
J'ai écrit une méthode (voir ci-dessous) qui extrait le nom de domaine d'une URL et qui utilise une correspondance simple. En réalité, il extrait le bit entre le premier "://"
(ou l'index 0
s'il n'y a pas de "://"
contenu) et le premier "/"
suivant (ou l'index String.length()
s'il n'y a pas de "/"
suivant). Le dernier bit "www(_)*."
restant est coupé. Je suis sûr qu'il y aura des cas où ce ne sera pas assez bon mais ça devrait l'être assez dans la plupart des cas!
Le message ci-dessus de Mike Samuel indique que la classe Java.net.URI
pourrait le faire (et a été préférée à la classe Java.net.URL
), mais j'ai rencontré des problèmes avec la classe URI
. Notamment, URI.getHost()
donne une valeur nulle si l’URL n’inclut pas le schéma, c’est-à-dire le bit "http(s)"
.
/**
* Extracts the domain name from {@code url}
* by means of String manipulation
* rather than using the {@link URI} or {@link URL} class.
*
* @param url is non-null.
* @return the domain name within {@code url}.
*/
public String getUrlDomainName(String url) {
String domainName = new String(url);
int index = domainName.indexOf("://");
if (index != -1) {
// keep everything after the "://"
domainName = domainName.substring(index + 3);
}
index = domainName.indexOf('/');
if (index != -1) {
// keep everything before the '/'
domainName = domainName.substring(0, index);
}
// check for and remove a preceding 'www'
// followed by any sequence of characters (non-greedy)
// followed by a '.'
// from the beginning of the string
domainName = domainName.replaceFirst("^www.*?\\.", "");
return domainName;
}
J'ai fait un petit traitement après la création d'objet URI
if (url.startsWith("http:/")) {
if (!url.contains("http://")) {
url = url.replaceAll("http:/", "http://");
}
} else {
url = "http://" + url;
}
URI uri = new URI(url);
String domain = uri.getHost();
return domain.startsWith("www.") ? domain.substring(4) : domain;
Il existe une question similaire Extraire le nom de domaine principal d'une URL donnée . Si vous regardez cette réponse , vous verrez que c'est très facile. Vous devez juste utiliser les utilitaires Java.net.URL
et String
- Split
private static final String hostExtractorRegexString = "(?:https?://)?(?:www\\.)?(.+\\.)(com|au\\.uk|co\\.in|be|in|uk|org\\.in|org|net|edu|gov|mil)";
private static final Pattern hostExtractorRegexPattern = Pattern.compile(hostExtractorRegexString);
public static String getDomainName(String url){
if (url == null) return null;
url = url.trim();
Matcher m = hostExtractorRegexPattern.matcher(url);
if(m.find() && m.groupCount() == 2) {
return m.group(1) + m.group(2);
}
else {
return null;
}
}
Explication: La regex a 4 groupes. Les deux premiers sont des groupes ne correspondant pas et les deux suivants sont des groupes correspondants.
Le premier groupe ne correspondant pas est "http" ou "https" ou ""
Le deuxième groupe ne correspondant pas est "www." ou ""
Le deuxième groupe correspondant est le domaine de premier niveau
Le premier groupe correspondant est tout ce qui suit les groupes non correspondants et tout ce qui précède le domaine de premier niveau
La concaténation des deux groupes correspondants nous donnera le nom de domaine/hôte.
PS: Notez que vous pouvez ajouter un nombre quelconque de domaines pris en charge à la regex.
essayez celui-ci: Java.net.URL;
JOptionPane.showMessageDialog (null, getDomainName (nouvelle adresse URL (" https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains ")));
public String getDomainName(URL url){
String strDomain;
String[] strhost = url.getHost().split(Pattern.quote("."));
String[] strTLD = {"com","org","net","int","edu","gov","mil","arpa"};
if(Arrays.asList(strTLD).indexOf(strhost[strhost.length-1])>=0)
strDomain = strhost[strhost.length-2]+"."+strhost[strhost.length-1];
else if(strhost.length>2)
strDomain = strhost[strhost.length-3]+"."+strhost[strhost.length-2]+"."+strhost[strhost.length-1];
else
strDomain = strhost[strhost.length-2]+"."+strhost[strhost.length-1];
return strDomain;}
Si l'URL d'entrée est une entrée utilisateur. cette méthode donne le nom d'hôte le plus approprié. si non trouvé redonne l'URL d'entrée.
private String getHostName(String urlInput) {
urlInput = urlInput.toLowerCase();
String hostName=urlInput;
if(!urlInput.equals("")){
if(urlInput.startsWith("http") || urlInput.startsWith("https")){
try{
URL netUrl = new URL(urlInput);
String Host= netUrl.getHost();
if(Host.startsWith("www")){
hostName = Host.substring("www".length()+1);
}else{
hostName=Host;
}
}catch (MalformedURLException e){
hostName=urlInput;
}
}else if(urlInput.startsWith("www")){
hostName=urlInput.substring("www".length()+1);
}
return hostName;
}else{
return "";
}
}
Tout ce qui précède est bon. Celui-ci me semble très simple et facile à comprendre. Excusez les citations. Je l'ai écrit pour Groovy dans une classe appelée DataCenter.
static String extractDomainName(String url) {
int start = url.indexOf('://')
if (start < 0) {
start = 0
} else {
start += 3
}
int end = url.indexOf('/', start)
if (end < 0) {
end = url.length()
}
String domainName = url.substring(start, end)
int port = domainName.indexOf(':')
if (port >= 0) {
domainName = domainName.substring(0, port)
}
domainName
}
Et voici quelques tests junit4:
@Test
void shouldFindDomainName() {
assert DataCenter.extractDomainName('http://example.com/path/') == 'example.com'
assert DataCenter.extractDomainName('http://subpart.example.com/path/') == 'subpart.example.com'
assert DataCenter.extractDomainName('http://example.com') == 'example.com'
assert DataCenter.extractDomainName('http://example.com:18445/path/') == 'example.com'
assert DataCenter.extractDomainName('example.com/path/') == 'example.com'
assert DataCenter.extractDomainName('example.com') == 'example.com'
}
Dans mon cas, je n'avais besoin que du domaine principal et non du sous-domaine (pas de "www" ou quel que soit le sous-domaine):
public static String getUrlDomain(String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost();
String[] domainArray = domain.split("\\.");
if (domainArray.length == 1) {
return domainArray[0];
}
else {
return domainArray[domainArray.length - 2] + "." + domainArray[domainArray.length - 1];
}
}
Avec cette méthode, l'url " https://rest.webtoapp.io/llSlider?lg=fr&t=8 " aura pour le domaine "webtoapp.io".