Obsługa wyjątku InputStreamReader z URL

0

Cześć,

próbuje zrobić zadanie w którym mam wysłać zapytanie HTTP Get i pobrać dane. Jeśli zapytanie się nie uda, mam zwrócić wiadomość, oraz status HTTP. Dane pobieram z API udostępnionego przez Github:

try {
    URL urlUser = new URL("https://api.github.com/users/blablabla");
    InputStreamReader readUserData = new InputStreamReader(urlUser.openStream());
    Owner user = new Gson().fromJson(readUserData, Owner.class);
    System.out.println(user.getLogin());
} catch (Exception e) {
    System.out.println(e.getMessage());
}

stworzyłem specjalną klasę Owner, która ma wszystkie pola znajdujące się w Jsonie, który dostaje w odpowiedzi.

Mam jednak problem z pobraniem potrzebnych danych w przypadku podania nieprawidłowego loginu. W Postmanie wygląda to tak:

screenshot-20220915180610.png

A przy użyciu swojego programu dostaje

java.io.FileNotFoundException: https://api.github.com/users/blabererelabla
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1993)
	at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589)
	at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:224)
	at java.base/java.net.URL.openStream(URL.java:1161)
	at pl.szymanski.githubInformationFinder.Service.RepositoryService.main(RepositoryService.java:49)

Process finished with exit code 0

i nie mogę znaleźć tam informacji na temat zwróconych danych.

Może powinienem użyć czegoś innego niż InputStreamReader - próbowałem z HTTPClient i innymi znalezionymi w internecie, ale nigdzie nie mogę znaleźć potrzebnych informacji.

2

W tego typu zadaniach, powinieneś zastosować klienta HTTP. Jest sporo bibliotek dla Java np. HttpClient, OkHttp,Jetty,Netty, Retrofit itp.
Przykładów użycia też można znaleźć sporo. Wujek Google na pewno pomoże.
Jaki wybrać ? Nie wiem, każdy ma swoje plusy i minusy. Przy tak prostym zadaniu, tak naprawdę nie ma to znaczenia.

W Twoim przypadku, po wywołaniu request ( zapytania) bezwzględnie należy sprawdzić status odpowiedzi ( o ile wcześniej nie wystąpi problem np. z timeout).
Przy poprawnym wyniku, zwykle powinno to być 200/OK - deserializujemy JSON do wymaganego obiektu.
Inny status ( znowu zwykle !! ) świadczy o jakimś problemie i wtedy powinno się oddzielnie obsłużyć taki przypadek.

O czym warto wiedzieć:

  1. Trzeba poznać REST API - co to jest, filozofia działania, jakie ma statusy wynikowe itp.
  2. Trzeba poznać dokumentację API danego serwisu bo np. status 200/OK to nie jedyny status poprawnie wykonanej operacji,
1

Z drugiej strony, można pójść na łatwiznę i pozostawić to co zrobiłeś.
Założenie jest proste - jak występuje wyjątek, no to jest źle i niedobrze i można ten wyjątek specjalnie obsłużyć np. wymuszając kolejne logowanie.
Jak jest dobrze, czyli wyjątek nie wystąpił - to deserializuje się JSON i koniec.

Osobiście nie polecam tej drogi ..

0

Twoim błędem jest to, że zakładasz, że istnieje odpowiedź. HttpURLConnection (po którym dziedziczy HttpsURLConnection którego używasz) pozwala dorwać się do dwóch streamów:

  • głównego, przez getInputStream(), który da ci info z odpowiedzią - jeśli takowa istnieje
  • drugiego, przez getErrorStream(), który nie będzie pusty kiedy coś pójdzie nie tak

Jeśli chcesz to obsłużyć to nie próbuj dorwać się do contentu zanim nie sprawdzisz, w jakim stanie jest połączenie. Najlepiej po prostu sobie zrzutować:

HttpsURLConnection connection = (HttpsURLConnection) new URL("https://api.github.com/users/blabla").openConnection();

I potem masz dostęp do wszelkiego rodzaju pomocniczych metod:

connection.getResponseCode(); // zwraca 404
connection.getResponseMessage(); // zwraca "Not found"

// ewentualnie przez strumienie - ale to musisz decydować na podstawie responseCode
connection.getInputStream(); // kiedy serwer zwróci odpowiedź
connection.getErrorStream(); // kiedy serwer zwróci jakiś 4xx czy 5xx

1 użytkowników online, w tym zalogowanych: 0, gości: 1