Hej!
Piszę w Javie modyfikator schowka systemowego.
Potrafię już rozpoznać jego typ (czy schowek jest dostępny w postaci plaintext).
Chciałbym sprawdzić czy tekst schowka prowadzi do jakiejkolwiek strony internetowej (czy jest linkiem).
Nie interesuje mnie strona a wynikami wyszukiwań w Google (tekst "forum" wpisany w pasku przeglądarki prowadzi do niej).
Wyrażenia regularne nie chcą działać, gdyż pojawiają się też różne dziwne linki.
Pozdrawiam!
Sprawdzanie czy link prowadzi do strony
- Rejestracja: dni
- Ostatnio: dni
- Rejestracja: dni
- Ostatnio: dni
Nie pisałem nic sieciowego jeszcze ale może po prostu spróbuj wywołać na danym tekście metodę ping. Wtedy po otrzymanej odpowiedzi z serwera nie tylko dowiesz się czy tekst jest linkiem ale też możesz sprawdzić czy serwer odpowiada czy nie.
- Rejestracja: dni
- Ostatnio: dni
Dzięki! Wpadłem właśnie na taki pomysł jakieś 10 minut temu.
Coś w stylu:
public static boolean isItValidLink (String linkCadidate) {
HttpURLConnection connection = null;
try {
/*
* The next line can throw a MalformedURLException.
*/
URL u = new URL(linkCadidate);
/*
* The next two lines can throw many kinds of exceptions.
*/
connection = (HttpURLConnection) u.openConnection();
connection.setRequestMethod("HEAD");
/*
* Returns -1 if no code can be discerned from the response (i.e., the response is not valid HTTP).
*/
if (connection.getResponseCode() == -1)
return false;
} catch (Exception e) {
return false;
}
return true;
}
Czekam na konstruktywną krytykę tego kodu.
- Rejestracja: dni
- Ostatnio: dni
Niestety dla: wp.pl wyrzuca wyjątek... tzn. nie jest to uznawane za URL przez Javę.
- Rejestracja: dni
- Ostatnio: dni
Pokaż cały kod
- Rejestracja: dni
- Ostatnio: dni
Przecież wp.pl nie jest linkiem.
- Rejestracja: dni
- Ostatnio: dni
Dla wp.pl czy też www.wp.pl nie działa opakowanie w javowego URLa.
Dla zdjęcia na facebooku - plik JPG (String rozpoczynający się od https://scontent.fwaw3-1.fna.fbcdn.net/hprofile-xpa1/v/t1.0-1/12105886...) nie działa z kolei ping.
Dlaczego tak się dzieje?
String linkCandidate = "www.wp.pl";
URL u = new URL(linkCadidate);
Wyrzuca wyjątek MalformedURLException. To samo dla "wp.pl".
Ping zależny od systemu:
public static boolean isReachableByPing(String host) {
try{
String cmd = "";
if(System.getProperty("os.name").startsWith("Windows")) {
// For Windows
cmd = "ping -n 1 " + host;
} else {
// For Linux and OSX
cmd = "ping -c 1 " + host;
}
Process myProcess = Runtime.getRuntime().exec(cmd);
myProcess.waitFor();
if(myProcess.exitValue() == 0) {
return true;
} else {
return false;
}
} catch( Exception e ) {
e.printStackTrace();
return false;
}
}
Nie działa dla zdjęcia na facebooku.
Z debuggera wiem, że myProcess.exitValue() wyrzuca 1.
Why?
Z góry dziękuję.
Zapomniałem dodać. Jest to publicznie dostępne zdjęcie.
Klikam prawym i daję na Copy Image Location w Mozilli Firefox.
Sorry, że rozpisałem kilka postów, powinien być jeden :p
- Rejestracja: dni
- Ostatnio: dni
www.wp.pl też nie jest linkiem, umieść w pliku html
<a href="www.wp.pl">Wirtualna Polska</a>
i spróbuj się połączyć.
Dokładniej, to jest link, ale nie do serwera tylko do pliku o nazwie www.wp.pl, który musi się znajdować obok pliku html z tym linkiem.
Poprawny URL rozpoczyna się od protokołu, np.
new URL("file://www.wp.pl");
new URL("http://www.wp.pl");
new URL("https://www.wp.pl");
Jeśli chodzi o ping, to nie wiem jaka jest wartość zmiennej host.
Polecenie
Process p = Runtime.getRuntime().exec("ping scontent.fwaw3-1.fna.fbcdn.net");
działa poprawnie. Być może Ty pingujesz do zdjęcia :P, a nie do serwera.
- Rejestracja: dni
- Ostatnio: dni
www.wp.pl też nie jest linkiem, umieść w pliku html
Dziękuję za odpowiedź!
Nie rozumiemy się, bo źle napisałem. Chodzi mi o "link" podany jako String w Javie.
Celem mojego programu (podprogramu) jest sprawdzenie dostępności danego adresu.
Prościej: co stanie się, jeśli wpiszemy ten String do paska adresu w przeglądarce.
Nie interesuje mnie strona Google z wynikami wyszukiwań (od kiedy większość przeglądarek ma taką funkcję, że z paska adresu możemy wyszukiwać jak w Google).
Interesuje mnie dostępność zarówno zdjęć czy innych plików, jak i innych nazw (np. wp.pl), z którymi można nawiązać połączenie.
Dlatego ani **ping **ani połączenie po próbie utworzenia URLa niezawsze działa... :(
Jeśli chodzi o ping, to nie wiem jaka jest wartość zmiennej host.
PolecenieProcess p = Runtime.getRuntime().exec("ping scontent.fwaw3-1.fna.fbcdn.net");
działa poprawnie. Być może Ty pingujesz do zdjęcia :P, a nie do serwera.
Tak pingowałem do zdjęcia.
Zauważyłem, że jeśli sprawdzę czy conajmniej jedna metoda (ping albo URL) nawiąże połączenie i zwróci true, można się połączyć, ale nie wiem czy jest to w pełni poprawne rozwiązanie.
Z góry dziękuję!
- Rejestracja: dni
- Ostatnio: dni
Ty czegoś nie rozumiesz, jeśli wpiszesz w pasku przeglądarki ciąg znaków np. jasna.dupa, to przeglądarka dopisze z przodu protokół (http://) oraz ciąg www i spróbuje się połączyć z adresem http://www.jasna.dupa. Natomiast konstruktor w klasie URL niczego nie dopisuje z przodu, Ty musisz podać poprawny adres, łącznie z protokołem.
- Rejestracja: dni
- Ostatnio: dni
Dziękuję za odpowiedź.
U mnie dopisuje z przodu tylko www.
Program ma być na tyle inteligentny, że rozpozna również skrócone nazwy :)
nietylko ładnie sformatowane URLe.
Za wiki:
Dzięki DNS nazwa mnemoniczna, np. pl.wikipedia.org jest tłumaczona na odpowiadający jej adres IP, czyli 91.198.174.192.
Pokusiło mnie to o trzecią metodę...
Podsumuję.
- Metoda sprawdza czy da się utworzyć na podstawie danego Stringu URLa oraz czy strona o tym URLu jest dostępna:
public static boolean isItValidLink (String linkCadidate) {
HttpURLConnection connection = null;
try {
/*
* The next line can throw a MalformedURLException.
*/
URL u = new URL(linkCadidate);
/*
* The next two lines can throw many kinds of exceptions.
*/
connection = (HttpURLConnection) u.openConnection();
connection.setRequestMethod("HEAD");
/*
* Returns -1 if no code can be discerned from the response (i.e., the response is not valid HTTP).
*/
if (connection.getResponseCode() == -1)
return false;
} catch (Exception e) {
return false;
}
return true;
}
- Metoda pinguje dany String.
public static boolean isReachableByPing(String host) {
try{
String cmd = "";
if(System.getProperty("os.name").startsWith("Windows")) {
// For Windows
cmd = "ping -n 1 " + host;
} else {
// For Linux and OSX
cmd = "ping -c 1 " + host;
}
Process myProcess = Runtime.getRuntime().exec(cmd);
myProcess.waitFor();
if(myProcess.exitValue() == 0) {
return true;
} else {
return false;
}
} catch (Exception e ) {
e.printStackTrace();
return false;
}
}
- Po trzecie klasa InetAdress.
import java.net.InetAddress;
W metodzie main:
System.out.println(ClipboardLinkShortener.isReachableByPing("www.wp.pl"));
System.out.println(ClipboardLinkShortener.isReachableByPing("wp.pl"));
System.out.println(ClipboardLinkShortener.isReachableByPing
("https://scontent-waw1-1.xx.fbcdn.net/hphotos-xft1/t31.0-8/1614068_820991184585112_155787083_o.jpg"));
System.out.println();
System.out.println(ClipboardLinkShortener.isItValidLink("www.wp.pl"));
System.out.println(ClipboardLinkShortener.isItValidLink("wp.pl"));
System.out.println(ClipboardLinkShortener.isItValidLink
("https://scontent-waw1-1.xx.fbcdn.net/hphotos-xft1/t31.0-8/1614068_820991184585112_155787083_o.jpg"));
System.out.println();
System.out.println(InetAddress.getByName("wp.pl").isReachable(5000));
System.out.println(InetAddress.getByName("www.wp.pl").isReachable(5000));
System.out.println(InetAddress.getByName("https://scontent-waw1-1.xx.fbcdn.net/hphotos-xft1/t31.0-8/1614068_820991184585112_155787083_o.jpg").isReachable(5000));
Co daje mi:
true
true
false
false
false
true
false
false
Exception in thread "main" java.net.UnknownHostException: https://scontent-waw1-1.xx.fbcdn.net/hphotos-xft1/t31.0-8/1614068_820991184585112_155787083_o.jpg
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$1.lookupAllHostAddr(Unknown Source)
at java.net.InetAddress.getAddressesFromNameService(Unknown Source)
at java.net.InetAddress.getAllByName0(Unknown Source)
at java.net.InetAddress.getAllByName(Unknown Source)
at java.net.InetAddress.getAllByName(Unknown Source)
at java.net.InetAddress.getByName(Unknown Source)
at ClipboardLinkShortener.main(ClipboardLinkShortener.java:167)
Wniosek: alternatywa pierwszej oraz drugiej metody to może być rozwiązanie, ale czy na pewno poprawne?
- Rejestracja: dni
- Ostatnio: dni
U mnie dopisuje z przodu tylko www.
Mylisz się, dopisuje również protokół, ale go nie wyświetla. Skopiuj adres z paska przeglądarki do schowka i wklej do jakiegoś edytora.
Co Cię powstrzymuje przed najbardziej naturalnym rozwiązaniem: samemu uzupełniać kandydata na link protokołem z przodu? Coś w rodzaju
import java.net.*;
public class Test
{
public static void main(String[] args)
{
System.out.println(isItValidLink("wp.pl"));
System.out.println(isItValidLink("www.wp.pl"));
System.out.println(isItValidLink("http://www.wp.pl"));
System.out.println(isItValidLink("https://www.wp.pl"));
System.out.println(isItValidLink("http://jasna.dupa"));
}
public static boolean isItValidLink (String linkCandidate)
{
String[] urls;
if(linkCandidate.toLowerCase().startsWith("https:"))
{
urls = new String[]{linkCandidate,linkCandidate.replace("https:","http:")};
}
else if(linkCandidate.toLowerCase().startsWith("http:"))
{
urls = new String[]{linkCandidate,linkCandidate.replace("http:","https:")};
}
else
{
urls = new String[]{"http://"+linkCandidate,"https://"+linkCandidate};
}
String protocol = "";
HttpURLConnection connection = null;
for(String url:urls)
{
try
{
if(protocol.isEmpty())
{
URL u = new URL(url);
connection = (HttpURLConnection) u.openConnection();
connection.setRequestMethod("HEAD");
if (connection.getResponseCode() != -1)
{
if(url.toLowerCase().startsWith("http:"))
{
protocol = "http";
}
else
{
protocol = "https";
}
}
}
}
catch (Exception e)
{
System.out.println(e);
}
}
System.out.println("Kandydat: "+linkCandidate+" Protokol: "+protocol);
return !protocol.isEmpty();
}
}
Wyjście
Kandydat: wp.pl Protokol: http
true
Kandydat: www.wp.pl Protokol: http
true
Kandydat: http://www.wp.pl Protokol: http
true
java.net.ConnectException: Connection timed out: connect
Kandydat: https://www.wp.pl Protokol: http
true
java.net.UnknownHostException: jasna.dupa
java.net.UnknownHostException: jasna.dupa
false
Działanie tej funkcji jest trochę mylące, zwraca true dla niepoprawnego adresu "https://www.wp.pl" - poprawia błędny protokół.
Przydatna byłaby też funkcja o sygnaturze
String createValidLink(String condidateLink)
- Rejestracja: dni
- Ostatnio: dni
Skopiuj adres z paska przeglądarki do schowka i wklej do jakiegoś edytora.
Tak, rzeczywiście dopisuje http.
Przydatna byłaby też funkcja o sygnaturze
String createValidLink(String condidateLink)
W dużej mierze byłoby to wydzielenie napisanego przez Ciebie kodu do tej metody.
Podoba mi się przedstawione przez Ciebie rozwiązanie, ale zastanawiam się jeszcze nad jakimiś kontrprzykładami.
Np. URLami z innych protokołów niż HTTP czy HTTPS, które również coś sobą reprezentują w przeglądarce.
Takie coś istnieje?
Z góry dzięki.