r10-05.doc

(496 KB) Pobierz
Szablon dla tlumaczy

W niniejszym rozdziale

·         Opcje komunikacji

·         Serwer godziny

·         Serwer pogawędek

Rozdział 10.

Komunikacja aplet-serwlet

Niniejszy rozdział przedstawia kilka technik, przy pomocy których aplety mogą komunikować się z serwletami. Zaprezentowane zostanie nieco inne podejście, niż to, jakiego można by się spodziewać. Zamiast przyjmować, że istnieje aplet i serwlet, które muszą się ze sobą porozumieć, przyjęto, że istnieje aplet, który musi porozumieć się z pewnym elementem serwera, i opisane zostanie, dlaczego czasami elementem tym powinien być serwlet.

Aby rozpocząć, proszę pomyśleć o apletach, które muszą porozumieć się z serwerem. Istnieje kilka dobrych przykładów. Proszę spojrzeć na aplet administracyjny, który działa na serwerze Java Web Server. Proszę pomyśleć, jak on działa — jest wykonywany na kliencie, ale konfiguruje serwer. Aby to uczynić, aplet i serwer muszą być w niemal stałym kontakcie. Inny przykład, proszę spojrzeć na jeden z popularnych apletów pogawędek. Jeden klient coś mówi, a cała reszta to widzi. Jak to działa? Na pewno aplety nie komunikują się ze sobą. Zamiast tego, każdy aplet wysyła swoje wiadomości do centralnego serwera, a serwer zajmuje się uaktualnieniem informacji innych klientów. W końcu, proszę sobie wyobrazić aplet, który śledzi cenę zbioru akcji i dokonuje ciągłego uaktualniania. Jak aplet poznaje aktualne ceny i, co ważniejsze, skąd wie, kiedy się one zmieniają? Odpowiedzią jest, że komunikuje się on z serwerem.

Opcje komunikacji

Zainteresowanie handlem akcjami wzrasta razem z indeksami giełdowymi, więc kontynuowany będzie hipotetyczny aplet, odpowiadający za akcje. Należy ostrzec, że aplet ten pozostanie hipotetyczny. Zostanie on wykorzystany jedynie jako punkt odniesienia w dyskusji nad kwestiami należącymi do komunikacji aplet-serwlet. Ale proszę się nie martwić, w dalszej części tego rozdziału występuje duża ilość kodu przedstawiająca techniki tu opisane, jedynie w nieco prostszych przykładach.

Ten aplet akcji musi pobierać ceny z jakiegoś serwera. Przyjmując, że jest to zwykły, niegodny zaufania aplet, jest tyko jedno wyjście — z komputera, z którego został pobrany. Każda próba połączenia się z innym komputerem daje wynik w SecurityException, tak więc należy przyjąć, że aplet pobiera ceny z serwera, z którego został pobrany[1]. Pytanie pozostaje — jak aplet i serwer mogą się ze sobą porozumiewać?

Aplety godne i niegodne zaufania

Kiedy aplet Javy zostaje osadzony w stronie WWW, przeglądarka może pobrać go i wykonać automatycznie. Jeżeli się nad tym zastanowić, jest to bardzo niebezpieczna sprawa. Tak więc, aby chronić klienta, JDK 1.0 przyjmował, że wszystkie aplety są niegodne zaufania i uruchamiał je pod kontrolą SecurityManager, który w poważny sposób ograniczał ich funkcjonalność. Na przykład, menedżer bezpieczeństwa zapewniał niemożność apletów do zapisywania informacji w systemie plików użytkownika, odczytywania pewnych właściwości systemu, przyjmowania przychodzących połączeń przez porty, czy też uruchamiania połączeń wychodzących z każdym komputerem, który nie był serwerem macierzystym. Własności te zabezpieczały klienta, ale ograniczały użyteczność apletów.

Konsekwentnie, JDK 1.1 wprowadził koncepcję apletów godnych zaufania — apletów, które mogły działać, jak zwykłe aplikacje z pełnym dostępem do komputera klienta. Aby aplet został uznany za godny zaufania, musi zostać elektronicznie podpisany przez osobę z firmy, której ufa klient (zaznaczonej w przeglądarce użytkownika). Podpis uwierzytelnia pochodzenie apletu i gwarantuje spójność podczas transferu tak, aby klient wiedział, że kod apletu nie został złośliwie zmieniony. Pozwoliło to na tworzenie bardziej użytecznych apletów, ale było podejściem typu wszystko albo nic.

Aby dać klientowi więcej kontroli, JDK 1.2 wprowadził złożony system kontroli dostępu. W tym nowym systemie, podpisany elektronicznie aplet może być częściowo uznany za godny zaufania i może on otrzymać pewne możliwości bez uzyskania pełnej kontroli nad systemem. Pozwala to na przyznawanie apletom nieznanego pochodzenia niewielkich przywilejów (takich jak zapis w jednym, konkretnym katalogu), bez dostarczania im możliwości przeglądania twardego dysku klienta. Producenci przeglądarek powoli wprowadzają obsługę nowych wersji JDK, ale na szczęście możliwe jest uaktualnienie JVM przeglądarki przy pomocy modułu rozszerzającego Java Plug-in, bezpłatnego produktu dostępnego pod adresem http://java.sun.com/products/plugin.

Połączenia przez HTTP i zwykłe porty

Przed stworzeniem JDK 1.1 i serwletów istniały dwie możliwości komunikacji aplet-serwer:

·         Połączenie HTTP apletu z programem CGI na serwerze. Aplet działa jak przeglądarka i żąda strony, analizując odpowiedź na własny użytek. Aplet może dostarczać informacji przy pomocy łańcucha zapytania lub danych POST oraz otrzymywać informacje ze zwracanej strony.

·         Połączenie przez zwykły port apletu z serwerem nie-HTTP. Serwer nie-HTTP może słuchać na danym porcie i porozumiewać się z apletem przy pomocy dowolnego protokołu, który zostanie wynegocjowany

Każde z tych podejść posiada wady i zalety. Połączenie HTTP apletu z programem CGI działa dobrze z następujących powodów:

·         Jest ono łatwe do napisania. Aplet może korzystać z klas java.net.URL i java.net.URLConnection w celu zarządzania kanałem komunikacji, a program CGI może zostać napisany tak, jak każdy inny.

·         Działa nawet w przypadku apletów pracujących za firewallem. Większość firewalli pozwala na połączenia HTTP, a nie pozwala na połączenia przez zwykłe porty.

·         Pozwala apletowi Javy na komunikację z programem napisanym w dowolnym języku. Program CGI nie musi być napisany w Javie. Może być to Perl, C, C++, lub każdy inny język.

·         Współpracuje z apletami utworzonymi przy pomocy JDK 1.0, tak więc pracuje z wszystkimi przeglądarkami posiadającymi obsługę Javy.

·         Pozwala na bezpieczną komunikację. Aplet może porozumiewać się z bezpiecznym serwerem przy pomocy zaszyfrowanego protokołu HTTPS (HTTP + SSL).

·         Program CGI może być wykorzystywany przez palety, a także przez przeglądarki. W przypadku przykładu akcji, program CGI może wykonywać podwójne zadanie, działając również jako wsparcie dla serwisu opartego na formularzach HTML. Zwłaszcza wygodne jest wykorzystanie przez aplet istniejącego programu CGI.

Jednak połączenie HTTP z programem CGI posiada również pewne wady:

·         Jest wolne. Z powodu paradygmatu HTTP żądanie-odpowiedź, aplet i program CGI nie mogą porozumiewać się interaktywnie. Dla każdego żądania i odpowiedzi muszą one tworzyć nowy kanał komunikacyjny. Dodatkowo istnieje pewne standardowe opóźnienie spowodowane uruchamianiem i inicjalizacją programu CGI w celu obsługi żądania.

·         Zazwyczaj wymaga, aby żądania były utworzone w formie okropnej tablicy par nazwa-wartość. Na przykład, kiedy przykładowy aplet akcji pyta o najwyższy dzienny kurs akcji Sun Microsystems, musi zadać pytanie przy pomocy okropnego łańcucha takiego jak akcja=sun&zapytanie=maxdzien.

·         Wymaga, aby wszystkie odpowiedzi były sformatowane według arbitralnego, wcześniej uzgodnionego standardu. Na przykład, kiedy przykładowy aplet akcji otrzymuje odpowiedź zawierającą najwyższy dzienny kurs akcji, musi dokładnie znać sposób analizy danych. Czy zwrócona cena rozpoczyna się znakiem dolara? Czy odpowiedź zawiera również czas wystąpienia ceny maksymalnej? A jeżeli tak, gdzie i w jakim formacie został on podany?

·         Jedynie aplet może rozpoczynać komunikację. Program CGI musi biernie czekać na żądanie od apletu, aby mógł zacząć odpowiadać. Jeżeli kurs akcji zmienia się, aplet może się o tym dowiedzieć jedynie wtedy, gdy zada właściwe pytanie.

Aplet i serwlet mogą się również porozumiewać poprzez połączenie zwykłym portem apletu z procesem serwera nie-HTTP. Podejście do posiada następujące zalety w stosunku do podejścia opartego na HTTP:

·         Pozwala na dwukierunkową stałą komunikację. Aplet i serwlet mogą wykorzystywać ten sam port (a nawet kilka portów) w celu interaktywnego porozumiewania się, wysyłania wiadomości w jedną i drugą stronę. Z powodów bezpieczeństwa, aplet musi zawsze rozpoczynać połączenie poprzez połączenie się z portem serwera na komputerze-serwerze, lecz po ustanowieniu połączenia przez port, każda strona może zapisywać do portu w dowolnym czasie. Pozwala to apletowi akcji na otrzymywanie uaktualnień cen akcji, kiedy tylko są one dostępne.

·         Pozwala na wykonywanie po stronie serwera bardziej wydajnego programu. Serwer nie-HTTP może być utworzony w celu obsługi żądania bezpośrednio bez uruchamiania zewnętrznego programu CGI w celu wykonania pracy.

Lecz połączenie przez zwykły port posiada również wady w stosunku do podejścia opartego na HTTP:

·         Nie działa w przypadku apletów działających za firewallami. Większość firewalli nie pozwala na połączenia przez zwykły port, tak więc nie pozwala na ten typ komunikacji aplet-serwlet. Tak więc mechanizm ten powinien zostać wykorzystywany jedynie wtedy, gdy pewne jest, że aplet nie będzie uruchomiony po drugiej stronie firewalla, na przykład w wypadku aplikacji Intranetu.

·         Tworzenie kodu działającego na serwerze może być stosunkowo skomplikowane. Zawsze musi istnieć pewien proces (taki, jak serwer kursów akcji) słuchający na dobrze znanym porcie serwera. Tworzenie takiej aplikacji w Javie jest łatwiejsze niż w C++, ale wciąż nie jest proste.

·         Może wymagać utworzenia nowego protokołu. Aplet i serwer muszą zdefiniować protokół, który wykorzystają w celu komunikacji. Chociaż protokół ten może być prostszy i bardziej wydajny niż HTTP, często musi zostać specjalnie napisany.

·         Serwer nie-HTTP nie może zostać bezpośrednio podłączony do przeglądarki WWW. Przeglądarki posługują się HTTP; nie mogą komunikować się z serwerem nie-HTTP.

Standardowe historyczne podejście wymagało od apletów porozumiewania się przy pomocy HTTP z programami CGI na serwerze. Jest to łatwe oraz działa we wszystkich typach przeglądarek, nawet tych pracujących za firewallami. Wykorzystanie połączenia przez zwykły port zostało generalnie zarezerwowane dla sytuacji, w której jest to absolutnie konieczne, takich jak ta, w której aplet i serwer wymagają komunikacji dwukierunkowej. A także, nawet w tym wypadku, często możliwe jest wykorzystanie połączeń HTTP w celu symulacji komunikacji dwukierunkowej, co ma służyć przejściu przez firewalle, jak przedstawione to będzie w późniejszym przykładzie.

Serwlety i serializacja obiektu

Niedawne wprowadzenie serwletów Javy i serializacji obiektów tchnęło nowe życie w te tradycyjne techniki komunikacji aplet-serwer. Serwlety zastępują wolno uruchamiające się programy CGI, poprawiając wydajność komunikacji aplet-serwer opartej na HTTP i czyniąc częste połączenia aplet-serwer możliwymi. Chociaż ogólnie rzecz biorąc prawdą jest, że aplet i serwlet ciągle wymagają czasu do ponownego otworzenia połączenia dla każdego żądania i odpowiedzi, aplet nie musi już dłużej czekać, aż serwer uruchomi program CGI w celu obsługi każdego z powtarzających się żądań.

Serializacja obiektów Javy uprościła kwestie związane z formatowaniem odpowiedzi. W związku z tym, że zarówno aplety, jak i serwlety napisane są w Javie, naturalnym jest, że powinny się one komunikować poprzez wymianę obiektów Javy. Na przykład, kiedy hipotetyczny aplet akcji pyta odpowiedni serwlet o najwyższy dzienny kurs akcji Suna, może otrzymać CenaAkcji w formie zserializowanego obiektu. Z niego można pobrać najwyższą wartość jako float oraz czas tej wartości jako Czas. Jest to spójne i dostarcza prostego zabezpieczenia typów. Proszę jednak pamiętać, że serializacja obiektów działa jedynie z apletami pracującymi wewnątrz przeglądarek obsługujących JDK 1.1 i późniejszych.

JDBC, RMI i CORBA

JDK 1.1 zawiera dwie dodatkowe własności wywierające wpływ na komunikację aplet-serwlet — JDBC i RMI. API JDBC (Java Database Connectivity — Łączność z Bazami Danych Javy), omówiony w rozdziale 9, „Łączność z bazami danych”, pozwala na połączenie się z relacyjną bazą danych na tym samym lub innym komputerze. Aplety Javy napisane od wersji JDK 1.1 mogą wykorzystywać JDBC do komunikowania się z bazą danych na serwerze. Ta przeznaczona do specjalnych celów komunikacja generalnie nie wymaga komunikacji aplet-serwlet. Jednak często okazuje się pomocne, aby aplet (szczególnie napisany dla JDK 1.0) nie łączył się bezpośrednio z bazą danych (lub z proxy ba serwerze WWW) a zamiast tego łączył się z serwletem obsługującym łączność z bazą danych zamiast apletu, jak opisano w ramce „Serwlety pośredniczące” w rozdziale 9, „Łączność z bazami danych”. Na przykład, aplet który chce wyszukać adres danej osoby może połączyć się z serwletem przy pomocy HTTP, przekazać nazwisko tej osoby wykorzystując parametry HTTP, po czym otrzymać adres jako specjalnie sformatowany łańcuch lub obiekt zserializowany. To zastosowanie komunikacji aplet-serwlet opiera się w znacznym stopniu na istniejących protokołach takich jak HTTP, tak więc nie zostanie tu szerzej opisane.

API RMI (Remote Method Invocation — Zdalne Wywoływanie Metod) pozwala apletowi na wywołanie metod obiektu Javy uruchomionego na serwerze oraz, w pewnych wypadkach, pozwala również obiektowi na serwerze na wywoływanie metod apletu. Zalety wykorzystania RMI w komunikacji aplet-serwer są bardzo znaczące:

·         Pozwala on apletom i obiektom serwera na porozumiewanie się przy pomocy eleganckiego, obiektowego paradygmatu wysokiego poziomu. Żądania mogą zostać wykonywane jako wywołania metod, z przekazaniem zserializowanych parametrów obiektu, kiedy jest to konieczne. Odpowiedzi mogą być otrzymywanie jako obiekty zserializowane lub nawet jako odwołania do innych zdalnych obiektów. Lecz nawet używanie słów żądanie i odpowiedź pokazuje na zbytnie przywiązanie do HTTP! Przy korzystaniu z RMI nie ma żadnych żądań i odpowiedzi, jedynie wywołania metod. Patrząc na przykład apletu akcji, aplet może pobrać maksymalny dzienny kurs akcji Suna poprzez wywołanie sun.pobierzMaxDzien(), gdzie sun jest obiektem Javy istniejącym na serwerze.

·         Pozwala on obiektom serwera na wykonywanie odwołań wstecznych do metod apletu. Na przykład, patrząc na aplet akcji, serwer może powiadomić zainteresowane aplety, że cena akcji zmieniła się poprzez wywołanie applet.update(akcja).

·         Możliwe jest przedostanie się przez firewalle (chociaż nie jest to zbyt dobry pomysł, ich obsługa przez obecne przeglądarki jest niedokładna). Warstwa transportująca RMI normalnie opiera się na bezpośrednich połączeniach przez port w celu wykonania swojej pracy. Kiedy jednak aplet wykonywane jest za firewallem, komunikacja przez zwykły port zawodzi. W tym przypadku warstwa transportująca RMI może zacząć działać wyłącznie wewnątrz protokołu HTTP[2].

Nie odbywa się to jednak bez pewnych kosztów. Wykorzystanie HTTP ma wpływ na wydajność, a paradygmat żądanie-odpowiedź HTTP nie obsługuje odwołań wstecznych. Wady RMI są równie zajmujące:

·         Jest on skomplikowany. Komunikacja RMI wykorzystuje specjalne klasy szkieletowe dla każdego zdalnego obiektu, a także wymaga rejestru nazw, w którym klienty mogą otrzymać odwołania do tych zdalnych obiektów.

·         Jest on obsługiwany przez niewielką ilość przeglądarek. Z wszystkich popularnych przeglądarek dostępnych w trakcie tworzenia niniejszej książki, jedynie Netscape Navigator 4 (i powyżej) zawierał obsługę RMI. Ani poprzednie wersje przeglądarki Netscape'a, ani żadne wersje Internet Explorera Microsoftu nie obsługują RMI bez instalacji odpowiedniego modułu rozszerzającego. (Chociaż ponieważ klasy RMI to czysta Java, udało się dodać RMI do Internet Explorera jako dodatkową bibliotekę.)

·         Może być on wykorzystywany jedynie przez klienty Javy. Obiekt serwera nie może być współdzielony przez przeglądarkę a nawet klienta C++.

Większa ilość informacji na temat programowania RMI dostępna jest w książkach „Java Network Programming” autorstwa Elliotte Rusty Harold (O'Reilly) i  „Java Distributed Computing” autorstwa Jima Farleya (O'Reilly).

CORBA (Common Object Request Broker Architecture — Wspólna Architektura Żądań Obiektów) to technologia podobna do RMI, która pozwala na komunikację pomiędzy obiektami rozproszonymi napisanymi w różnych językach. Przy pomocy CORBA'y i jej protokołu komunikacyjnego IIOP (Internet Inter-ORB Protocol), klient C++ może porozumiewać się z serwletem Javy. Przedstawienie tej techniki przekracza zakres niniejszej książki. Większa ilość informacji dostępna jest pod adresami http://www.omg.org i http://java.sun.com/products/jdk/idl.

Podejście hybrydowe

Teraz, kiedy przeanalizowane zostały już wszystkie opcje, pytanie pozostaje: jak przykładowy aplet akcji powinien porozumiewać się ze swoim serwerem cen akcji? Odpowiedź brzmi: to zależy.

Jeżeli można zagwarantować, że wszyscy potencjalni klienci posiadają jego obsługę, elegancja i moc RMI czynią go idealnym wyborem. Brzmi to jednak tak, jak przyjmowanie, że wszyscy znajomi uwielbiają dowcipy na temat Star Treka. Może to być prawda przy dokładnym wybieraniu przyjaciół (lub klientów), lecz generalnie nie zdarza się to w prawdziwym świecie.

Kiedy RMI nie jest dostępny, dwukierunkowe możliwości połączenia przez port nie-HTTP sprawiają, że wygląda ono atrakcyjnie. Niestety, ta dwukierunkowa komunikacja staje się nieistniejącą komunikacją, kiedy aplet kończy się na firewallu.

Zawsze jest stary sposób, komunikacja HTTP. Jest ono proste w implementacji i pracuje na każdym kliencie z obsługą Javy. A jeżeli można zagwarantować, że klient obsługuje JDK 1.1 (jest to łatwiejsze do zagwarantowania, niż obsługa RMI przez klientów), można wykorzystać serializację obiektów.

Przypuszczalnie najlepszym rozwiązaniem jest wykorzystanie wszystkich rozwiązań. Java sprawia, że możliwe jest połączenie technik komunikacji aplet-serwlet HTTP, nie-HTTP i RMI, umieszczając obsługę ich wszystkich w jednej aplikacji. Dlaczego ktoś miałby chcieć to zrobić? Dlatego, że jest to poręczna technika, kiedy aplet chce porozumieć się przy pomocy RMI lub protokołu nie-HTTP, lecz musi przełączyć się na HTTP, kiedy okaże się to potrzebne (w przypadkach takich jak znalezienie się przed firewallem). Poprzez zastosowanie tego samego serwera do obsługi wielu klientów, podstawowa logika serwera i stan serwera mogą być zebrane w jednym miejscu. Kiedy środowisko jest pod kontrolą można usunąć jeden lub więcej z tych protokołów. Lecz czy nie jest miło wiedzieć, że nie jest to konieczne?

Dla skomplikowanych aplikacji pracujących na serwerze aplikacji standardowym projektem jest udostępnienie zdalnego obiektu RMI klientom RMI, urządzenia słuchającego na portach klientom portów a serwletu klientom HTTP. Obiekty te wykorzystują wspólnie zbiór logicznych klas biznesowych w celu obsługi żądań klienta (podobnie jak w restauracji z wynosem można zamawiać poprzez telefon, faks lub pocztę elektroniczną). Jednak w pozostałej części niniejszego rozdziału zostanie to nieco uproszczone, i przedstawiona zostanie komunikacja RMI, przez porty i HTTP obsługiwana przez pojedynczy serwlet. Jeden serwlet, wiele protokołów dostępu.

Serwer godziny

W celu prostego przedstawienia każdej z technik komunikacji, napisany zostanie aplet proszący serwer o aktualną datę i godzinę. Aplet na początku wykorzystuje połączenie HTTP, później połączenie przez port nie-HTTP, a w końcu połączenie RMI. Oczywiście, aplet może normalnie pobierać obecny czas z systemu, na którym pracuje. Aby nadać temu przykładowi cień praktyczności, można przyjąć, że aplet potrzebuje dokładnego znacznika czasu dla jakiegoś zdarzenia i nie może polegać na tym, że komputer klienta posiada prawidłowo ustawiony zegar.

Aplet

W całym niniejszym podrozdziale wykorzystane będzie ten sam aplet. Szkielet kodu tego apletu, ApletGodziny jest przedstawiony na przykładzie 10.1. W tym momencie aplet ten po prostu tworzy interfejs użytkownika, na którym wyświetlane będą pobrane przez niego czasy, jak przedstawiono na rysunku 10-1. W dalszej części tego rozdziału zaimplementowane zostaną metody pobierzDataHttpTekst(), pobierzDataHttpObiekt(), pobierzDataPortTekst(), pobierzDataPortObiekt() i pobierzDataRMIObiekt().

Rysunek 10.1.

rys 10.1 — z płyty, ale uwaga do RedProw: kod spolszczony!!!!!

Interfejs użytkownika apletu ApletGodziny

Proszę zauważyć, że przykłady w niniejszym rozdziale korzystają z kilku metod JDK 1.0, które zostały zarzucone w JDK 1.1. Zostało to uczynione w celu poprawienie przenośności. Podczas kompilowania przykładów w nowych JDK wyświetlone zostaną ostrzeżenia na temat zarzucenia, mogą one jednak zostać bezpiecznie zignorowane.

Przykład 10.1.

ApletGodziny, bez ulepszeń

import java.applet.*;

import java.awt.*;

import java.io.*;

import java.util.*;

 

public class ApletGodziny extends Applet {

 

  TextField httpTekst, httpObiekt, portTekst, portObiekt, RMIObiekt;

  Button odswiez;

 

  public void init() {

    // Konstruowanie interfejsu użytkownika

 

    setLayout(new BorderLayout());

 

    // Po lewej stronie dodanie etykiet dla różnych mechanizmów komunikacji

    Panel zachod = new Panel();

    zachod.setLayout(new GridLayout(5, 1));

    zachod.add(new Label("Tekst HTTP: ", Label.RIGHT));

    zachod.add(new Label("Obiekt HTTP: ", Label.RIGHT));

    zachod.add(new Label("Tekst portu: ", Label.RIGHT));

    zachod.add(new Label("Obiekt portu: ", Label.RIGHT));

    zachod.add(new Label("Obiekt RMI: ", Label.RIGHT));

    add("Zachod", zachod);

 

    // Po prawej utworzenie pól tekstowych wyświetlających otrzymane wartości czasu

    Panel centrum = new Panel();

    centrum.setLayout(new GridLayout(5, 1));

 

    httpTekst = new TextField();

    httpTekst.setEditable(false);

    centrum.add(httpTekst);

 

    httpObiekt = new TextField();

    httpObiekt.setEditable(false);

    centrum.add(httpObiekt);

 

    portTekst = new TextField();

    portTekst.setEditable(false);

    centrum.add(portTekst);

 

    portObiekt = new TextField();

    portObiekt.setEditable(false);

    centrum.add(portObiekt);

 

    RMIObiekt = new TextField();

    RMIObiekt.setEditable(false);

    centrum.add(RMIObiekt);

 

    add("Centrum", centrum);

 

    // Na dole utworzenie przycisku uaktualniającego czas

    Panel poludnie = new Panel();

    odswiez = new Button("Odswież");

    poludnie.add(odswiez);

    add("Poludnie", poludnie);

  }

 

  public void start() {

    odswiez();

  }

 

  private void odswiez() {

    // pobranie i wyświetlenie wartości czasu

    httpTekst.setText(pobierzDataHttpTekst());

    httpObiekt.setText(pobierzDataHttpObiekt());

    portTekst.setText(pobierzDataPortTekst());

    portObiekt.setText(pobierzDataPortObiekt());

    RMIObiekt.setText(pobierzDataRMIObiekt());

  }

 

  private String pobierzDataHttpTekst() {

    // Pobranie obecnego czasu przy pomocy opartego na tekście połączenia HTTP

    return "niedostępny";

...

Zgłoś jeśli naruszono regulamin