Do Redaktora: w tym rozdziale przewijają się książki, których nie wydaliśmy, może by tak wpisać nasze?
Od czasu, kiedy napisane zostało pierwsze wydanie niniejszej książki, serwlety i platforma Javy działająca po stronie serwera zyskała popularność, której nie można było spodziewać się w najśmielszych marzeniach. Postępuje przyłączanie tych mechanizmów do istniejących. Producenci serwerów WWW oferują obecnie obsługę serwletów jako standardową własność swojego oprogramowania. W specyfikacji Java 2, Enterprise Edition (J2EE) serwlety istnieją jako podstawowy składnik, a niemożliwym jest obecnie znalezienie producenta serwerów aplikacji, którego produkt nie zawierałby skalowalnej implementacji serwletów. Jest to jednak więcej niż zjawisko napędzane przez producentów. Serwlety stały się podstawą dla JavaServer Pages (JSP) i innych szkieletów tworzenia stron WWW, a technologia serwletów obsługuje aktualnie tak często odwiedzane witryny, jak ESPN.com i AltaVista.com.
W związku z tym nie jest zaskakującym fakt, że krajobraz serwletów wygląda nieco inaczej niż w czasach pierwszego wydania. Interfejs serwletów (Servlet API) został poddany dwóm przeglądom, a trzeci jest w trakcie przygotowań. Znajome z początków istnienia serwletów firmy Live Software i New Atlanta, które niegdyś zarabiały sprzedając mechanizmy serwletów (nazywane teraz kontenerami serwletów) Jrun i ServletExec, zostały zauważone i wykupione przez większe firmy zorientowane na WWW, odpowiednio przez Allaire i Unify. Oferują one teraz wiele własności wykraczających poza podstawową obsługę serwletów w celu odróżnienia się od innych.
Co dziwne, oficjalne pakiety javax.servlet i javax.servlet.http były pierwszymi klasami Javy, które zostały oficjalnie rozprowadzone jako Open Source. Zostały one przeniesione do projektu Apache Software Foundation (ASF), i można je aktualnie odnaleźć pod adresem http://jakarta.apache.org. Pakiety te dalej zgodne są ze specyfikacją Servlet API, jednak poprawa błędów i uaktualnianie specyfikacji znajduje się teraz w rękach w zaufanych programistów Open Source — włączając autora, który miał niedawno okazję poprawienia obsługi warunkowego żądania GET w HttpServlet. Dodatkowo, serwer, który jest traktowany jako wzorcowa implementacja Servlet API, został również przeniesiony do ASF i udostępniony jako Open Source pod nazwą Apache Tomcat. Od tego czasu Tomcat stał się jednym z najpopularniejszych kontenerów serwletów. Większa ilość informacji na ten temat dostępna jest pod adresem http://opensource.org.
Świat serwletów zmienił się, a niniejsza książka zawiera uaktualnione informacje. Całą wiedzę potrzebną do programowania serwletów Javy, od początku do końca. Pierwsze pięć rozdziałów opisuje podstawy — czym są serwlety, jakie działania wykonują oraz w jaki sposób pracują. Następne 15 rozdziałów zawiera informacje zaawansowane — opisuje działania podejmowane najczęściej przy pomocy serwletów oraz najpopularniejsze narzędzia do tego służące. Można tam znaleźć wiele przykładów, kilka wskazówek i ostrzeżeń, a nawet opisy kilku prawdziwych błędów, które umknęły uwagi korektorów technicznych.
Niniejsze wydanie książki opisuje wersję 2.2 Servlet API, która osiągnęła stan „wersji publicznej” w sierpniu 1999, a stan „wersji ostatecznej” w grudniu 1999. Wydanie pierwsze opisywało wersje 2.0. Zmiany pomiędzy wersjami 2.0 i 2.2 są znaczne:
· Zostały wprowadzone zasady definiujące dystrybucje serwletów pomiędzy kilkoma serwerami wspierającymi.
· Serwlety korzystają aktualnie z dołączanych aplikacji WWW, które mogą być konfigurowane i wdrażane w sposób niezależny od serwera.
· Znacznie poprawione zostało bezpieczeństwo serwletów.
· Serwlety mogą teraz przekazywać obsługę żądań innym składnikom serwera.
· Serwlety mogą teraz dzielić się informacjami przy pomocy ich ServletContext
· Istnieje sposób przystosowania serwletów do obsługi dostępu rozproszonego.
· Serwlety posiadają teraz ściślejszą kontrolę nad zarządzaniem sesją.
· Dodane zostało buforowanie odpowiedzi.
· Rozszerzona została kontrola nad nagłówkami HTTP.
· Aktualnie może być zastosowana bardziej zaawansowana obsługa błędów.
· API został „wyczyszczony” w celu nadania większej spójności i przewidywalności nazwom metod.
· Servlet API jest teraz zdefiniowany poprzez formalny dokument specyfikacji, a przyszłe uaktualnienia API są zarządzane przez formalny proces Java Specification Request (JSR).
· Serwlety są teraz zintegrowane z podstawową specyfikacją platformy Java 2, Enterpise Edition (J2EE).
Wszystkie te zmiany, oraz wiele innych drobnych usprawnień, są w pełni opisane w niniejszym nowym wydaniu. Drugie wydanie zawiera również obszerny opis najciekawszego obszaru programowania serwletów — technik tworzenia prawdziwych dynamicznych witryn opartych na serwletach. W niniejszym wydaniu znajdują się samouczki pięciu najpopularniejszych technologii tworzenia zawartości opartej na serwletach, należących do Open Source:
· JavaServer Pages (JSP), standard firmy Sun, tworzony i udostępniany w połączeniu z serwletami
· Tea, technologia utworzona przez Walt Disney Internet Group (dawniej GO.com), zastosowany w wielu bardzo często odwiedzanych stronach, takich jak ESPN.com, NFL.com, Disney.com, DisneyLand.com, GO.com i Movies.com
· WebMacro, utworzony przez Semiotek i wykorzystywany przez wyszukiwarkę AltaVista
· XMLC, utworzony przez Lutris Technologies w celu udostępnienia mocy technologii XML sieci WWW, wykorzystywany przez innowacyjne witryny takie jak customatix.com
· Element Construcion Set (ECS), utworzony przez Apache w celu obsługi najbardziej wymagających potrzeb programistycznych
Niniejsze drugie wydanie opisuje również WAP, Wireless Application Protocol (Protokół Aplikacji Bezprzewodowych) oraz wyjaśnia, jak tworzyć oparte na serwletach aplikacje WWW dla urządzeń bezprzewodowych.
W czasie pisania niniejszej książki, Servlet API 2.3 jest w trakcie tworzenia. Jednak nie został on jeszcze ukończony. W związku z tym tekst niniejszego wydania zawiera w różnych miejscach krótkie uwagi na temat zmian spodziewanych w z Servlet API 2.3. Dodatkowo, ostatni rozdział książki zawiera dokładniejszy opis próbnej specyfikacji Servlet API 2.3, udostępnionej w październiku 2000, który pozwala na zapoznanie się z najnowszymi własnościami Servlet API 2.3. Należy jednak zaznaczyć, że specyfikacje te ciągle podlegają zmianom, a ostateczna wersja może się nieco różnić od materiału tu przedstawionego.
Czytelnicy książki „Java Servlet Programming, 1st ed.”
do Red prow: tej książki nie wydaliśmy, może tak przeredagować tekst?
zorientują się, że niniejsza książka została obszernie uaktualniona do Servlet API 2.2 i, gdzie to tylko możliwe, Servlet 2.3. Każdy rozdział został znacząco poprawiony w porównaniu z pierwszym wydaniem, a także dodano sześć nowych rozdziałów opisujących techniki tworzenia zawartości opartej na serwletach, jak również nowy rozdział siódmy, „Serwlety korporacyjne i J2EE”, który opisuje integrację serwletów w platformie J2EE.
Ze względu na znaczący wpływ modelu aplikacji WWW na wszystkie aspekty programowania serwletów, poleca się czytelnikom pierwszego wydania przeczytanie każdego interesującego ich rozdziału oraz zwrócenie uwagi na nowe mechanizmy, które pozwalają na wykonanie tradycyjnych zadań. Czytelnicy dysponujący ograniczonym czasem powinni przejrzeć listę najbardziej znaczących zmian w podrozdziale „Organizacja”.
Dla kogo jest ta książka? Dla osób zainteresowanych tworzeniem aplikacji umieszczanych w sieci WWW. Dokładniej rzecz biorąc, niniejszą książką powinni zainteresować się:
· Programiści J2EE — serwlety są integralną częścią standardu Java 2, Enterpise Edition. Programiści tworzący aplikacje dla serwerów J2EE mogą nauczyć się jak najlepiej zintegrować serwlety z innymi podobnymi technologiami.
· Programiści JSP — JavaServer Pages (JSP) tworzone są na podstawie serwletów. Wykorzystanie pełnej mocy JSP wymaga zrozumienia serwletów, co też umożliwia niniejsza książka. Zawiera ona również samouczek JSP oraz czterech podstawowych konkurencyjnych technologii.
· Programiści apletów Javy — porozumiewanie się apletów z serwerem zawsze sprawiało problemy. Serwlety ułatwiają to zadanie poprzez dostarczenie apletom prostego w połączeniu agenta na serwerze.
· Programiści CGI — CGI jest popularną metodą rozszerzania funkcjonalności serwera WWW. Serwlety są elegancką i wydajną alternatywą tej techniki.
· Programiści innych technik serwerów — istnieje wiele alternatyw dla CGI, między innymi FastCGI, PHP, NSAPI, WAI, ISPAI, ASP, a teraz ASP+. Każda z nich posiada ograniczenia związane z przenośnością, bezpieczeństwem, wydajnością i/lub integracją z innymi źródłami danych. Serwlety przewyższają je w każdym z tych obszarów.
Podczas rozpoczynania pracy z niniejszą książką, niespodzianką dla autorów okazało się, że jedną z najtrudniejszych do określenia rzeczy jest docelowy czytelnik. Czy zna on Javę? Czy ma doświadczenie w programowaniu CGI lub innych aplikacji WWW? Czy miał już kontakt z serwletami? Czy zna HTTP i HTML, czy te skróty brzmią dla niego zupełnie niezrozumiale? Niezależnie od przyjmowanego poziomu doświadczenia, zawsze okazywało się, że książka będzie zbyt uproszczona dla jednych użytkowników, a zbyt zaawansowana dla drugich.
Ostatecznie zdecydowano się na zasadę, że niniejsza książka powinna zawierać w przeważającej części materiał oryginalny — można pominąć obszerne opisy tematów i koncepcji dobrze opisanych w sieci lub innych książkach. W tekście znaleźć można odwołania do tych zewnętrznych źródeł informacji.
Oczywiście zewnętrzne źródła informacji nie są wystarczające. Niniejsza książka zakłada, że czytelnicy dobrze znają język Java oraz podstawowe techniki programowania obiektowego. Jeżeli nie spełnia się tych założeń, polecane jest przygotowanie się poprzez przeczytanie ogólnej książki na temat programowania w Javie, takiej jak „Learning Java” autorstwa Patricka Niemeyera i Jonathana Knudsena (O'Reilly). W książce tej można jedynie krótko zapoznać się z rozdziałami na temat apletów i programowania Swing (graficznego), a skupić się na sieci i programowaniu wielowątkowym. Aby zacząć od razu naukę serwletów i uczyć się Javy w trakcie, polecane jest przeczytanie niniejszej książki równocześnie z „Java in a Nutshell” autorstwa Davida Flanagana (O'Reilly) lub innym podręcznikiem.
Niniejsza książka nie wymaga od czytelników doświadczenia w programowaniu WWW, HTTP i HTML. Nie zawiera jednak pełnego wprowadzenia lub wyczerpującego opisu tych technologii. Opisane zostaną podstawy potrzebne do efektywnego programowania serwletów, a szczegóły (takie jak pełna lista znaczników HTML i nagłówków HTTP 1.1) pozostawione zostaną innym źródłom.
W niniejszej książce znaleźć można ponad 100 przykładów serwletów. Ich kod jest całkowicie zawarty wewnątrz tekstu, możliwe jest jednak także pobranie przykładów zamiast ręcznego ich wpisywania. Kod przykładów, spakowany i gotowy do pobrania, można znaleźć pod adresem http://www.oreilly.com/catalog/jservlet2. Wiele z tych serwletów można zobaczyć w działaniu pod adresem http://www.servlets.com.
Wszystkie przykłady zostały przetestowane przy pomocy serwera Apache Tomcat 3.2 działającego w trybie samodzielnym, wirtualnej maszyny Javy (Java Virtual Machine — JVM) zawartej w Java Development KIT 1.1.8 i 1.2.2, zarówno pod Windows jak i Uniksem. Kilka zaawansowanych przykładów wymaga własności, których nie obsługuje Tomcat w trybie samodzielnym. W tym przypadku przykłady były testowane na różnych innych serwerach, jak opisano w tekście. Serwer Apache Tomcat jest oficjalną wzorcową implementacją Servlet API, i jest dostępny w licencji Open Source pod adresem http://jakarta.apache.org.
Niniejsza książka zawiera również zbiór klas narzędziowych — wykorzystywane są one przez serwlety przykładowe, mogą się także okazać przydatne przy tworzenie własnych. Klasy te zawarte są w pakiecie com.oreilly.servlet. Między innymi są to klasy pomagające serwletom w analizie parametrów, obsłudze wysyłania plików, generowaniu wieloczęściowych odpowiedzi (przepychanie serwera), negocjacji ustawień lokalnych i internacjonalizacji, zwracaniu plików, zarządzaniu połączeniami i pracy jako serwer RMI. Pakiet te zawiera również klasę wspomagającą komunikację apletów z serwletami. Od czasu pierwszego wydania dodane zostały nowe klasy pomagające serwletom w wysyłaniu wiadomości poczty elektronicznej, przechowywaniu odpowiedzi w pamięci podręcznej oraz automatycznym wykrywaniu obsługi Servlet API. Kod źródłowy większości pakietu com.oreilly.servlet zawarty jest w tekście, a pełna, aktualna wersja jest dostępna w formie elektronicznej (razem z dokumentacją javadoc) pod adresem http://www.servlets.com.[1]
Niniejsza książka składa się z 20 rozdziałów i 6 dodatków, są one następujące:
· Rozdział 1, „Wprowadzenie”. Wyjaśnia rolę i zalety serwletów Javy w tworzeniu aplikacji WWW. W drugim wydaniu dodane zostały dodatkowe informacje na temat serwerów.
· Rozdział 2, „Podstawy serwletów HTTP”. Zawiera krótkie wprowadzenie do HTTP i funkcji, jakie mogą pełnić serwlety HTTP. Przedstawia tworzenie prostej strony i wprowadza pojęcie dołączanej aplikacji WWW. Drugie wydanie opisuje aplikacje WWW i ich deskryptory oparte na XML.
· Rozdział 3, „Cykl życia serwletów”. Wyjaśnia szczegółowe informacje na temat sposobu i czasu ładowania serwletów, sposobu i czasu ich wykonywania, zarządzania wątkami oraz obsługi kwestii synchronizacji w systemie wielowątkowym. Opisane są również stany trwałe. Drugie wydanie zawiera nowe zasady kontekstowego przeładowywania i rejestracji serwletów, nowy podrozdział na temat pamięci podręcznej po stronie serwera oraz uwagę na temat super.init(config).
· Rozdział 4, „Pobieranie informacji”. Wprowadza najpopularniejsze metody wykorzystywane przez serwlety w celu pobrania informacji — na temat klienta, serwera, żądań klienta oraz samego siebie. Przedstawia również działanie ogólnej klasy służącej do wysyłania plików. Drugie wydanie opisuje ustawianie informacji w deskryptorze, pobieranie nazwy serwletu, dostęp do katalogów tymczasowych, obsługę kontekstowych parametrów początkowych, określanie wersji Servlet API, przypisywanie odwzorowania serwletów oraz dostęp do zasobów abstrakcyjnych. Przestawia również poprawiony, bardziej elastyczny składnik służący do wysyłania plików.
· Rozdział 5, „Wysyłanie informacji HTML”. Opisuje sposoby tworzenia kodu HTML przez serwlet, zwracania błędów, buforowania odpowiedzi, przekierowywania żądań, zapisywania danych w dzienniku zdarzeń serwera oraz wysyłania dostosowanych nagłówków HTML. Drugie wydanie zawiera nowy opis buforowania odpowiedzi, bardzo przydatny przykład przekierowywania oraz nowe podrozdziały na temat konfiguracji stron zawierających błędy i obsługi błędów.
· Rozdział 6, „Wysyłanie zawartości multimedialnej”. Opisuje różne interesujące dane, które może zwracać serwlet — zawartość WAP/WML dla urządzeń bezprzewodowych, dynamicznie tworzone obrazki, zawartość skompresowana oraz odpowiedzi wieloczęściowe. W drugim wydaniu dodano opis WAP/WML, listy plików powitalnych, dyskusję na temat PNG, usprawnioną pamięć podręczną rysunków po stronie serwera oraz więcej szczegółów na temat tworzenia zawartości skompresowanej.
· Rozdział 7, „Śledzenie sesji”. Opisuje sposoby tworzenia śledzenia stanu w bezstanowym protokole HTTP. Pierwsza część rozdziału opisuje tradycyjne techniki śledzenia sesji stosowane przez programistów CGI. Druga część opisuje sposoby zastosowania wbudowanej w Servlet API obsługi śledzenia sesji. Drugie wydanie zawiera zasady tworzenia sesji aplikacji WWW, materiał na temat nowych nazw metod sesji, dyskusję na temat zarządzania przekraczaniem czasu oraz śledzenie sesji oparte na apletach.
· Rozdział 8, „Bezpieczeństwo”. Wyjaśnia kwestie bezpieczeństwa związane z programowanie rozproszonym. Opisuje sposoby korzystania ze standardowych funkcji serwletów związanych z zarządzaniem kontami użytkowników oraz sposoby tworzenia bardziej zaawansowanego systemu przy pomocy dodatkowego uwierzytelniania i autoryzacji. Wyjaśni również rolę serwletów w bezpiecznej komunikacji SSL. W drugim wydaniu całkowicie przeredagowany.
· Rozdział 9, „Łączność z bazami danych”. Opisuje sposoby wykorzystania serwletów w wysokowydajnej łączności z bazami danych WWW. Zawiera samouczek JDBC. Drugie wydanie zawiera przykłady konfiguracji połączeń z plikami właściwości, nowy przykład księgi gości oraz nowy podrozdział opisujący JDBC 2.0.
· Rozdział 10, „Komunikacja aplet-serwlet”. Opisuje sposoby wykorzystania serwletów przez aplet, który musi porozumieć się z serwerem. Uaktualniony w drugim wydaniu.
· Rozdział 11, „Współpraca serwletów”. Opisuje powody komunikacji serwletów i sposoby ich współpracy przez dzielenie się informacjami lub wywoływanie sienie nawzajem. W drugim wydaniu całkowicie przeredagowany.
· Rozdział 12, „Serwlety korporacyjne i J2EE”. Opisuje zaawansowane własności serwletów wykorzystywane w witrynach korporacyjnych — dystrybucję ładunku i integrację składników J2EE. Nowość w drugim wydaniu.
· Rozdział 13, „Internacjonalizacja”. Opisuje sposoby, dzięki którym serwlet może odczytywać i tworzyć zawartość w różnych językach. Drugie wydanie opisuje zastosowanie javadoc w zarządzaniu kodowaniem i sposoby wykorzystywania nowych metod API w zarządzaniu wersjami lokalnymi.
· Rozdział 14, „Szkielet Tea”. Przedstawia szkielet Tea, elegancki, ale zarazem potężny mechanizm szablonów. Nowość w drugim wydaniu.
· Rozdział 15, „WebMacro”. Opisuje szkielet WebMacro, podobny do Tea lecz z kilkoma innymi decyzjami projektanckimi. Nowość w drugim wydaniu.
· Rozdział 16, „Element Construction Set”. Zawiera krótki opis ECS, obiektowego podejścia do tworzenia strony. Nowość w drugim wydaniu.
· Rozdział 17, „XMLC”. Przegląd XMLC, podejścia do tworzenia strony opartego na XML. Nowość w drugim wydaniu.
· Rozdział 18, „JavaServer Pages”. Wyjaśnia JSP, standardową technologię firmy Sun, w której strony WWW są automatycznie wkompilowane w serwer. Nowość w drugim wydaniu.
· Rozdział 19, „Informacje dodatkowe”. Przedstawia dodatkowe przykłady serwletów i podpowiedzi, które nie zmieściły się w żadnym z poprzednich rozdziałów. Drugie wydanie zawiera analizator parametrów zlokalizowanych, nową klasę poczty elektronicznej oraz uaktualniony podrozdział na temat wyrażeń regularnych, nowy podrozdział na temat dodatkowych narzędzi oraz dodatkowe podpowiedzi na temat wydajności.
· Rozdział 20, „Zmiany w Servlet API 2.3”. Opisuje zmiany w nadchodzącej wersji 2.3 Servlet API, który ma zostać udostępniony w połowie 2001. Nowość w drugim wydaniu.
· Dodatek A, „Krótki opis Servlet API”. Zawiera pełny opis klas, metod i zmiennych w pakiecie javax.servlet. W drugim wydaniu uaktualniony do Servlet API 2.2
· Dodatek B, „Krótki opis HTTP Servlet API”. Zawiera pełny opis klas, metod i zmiennych w pakiecie javax.servlet.http. W drugim wydaniu uaktualniony do Servlet API 2.2
· Dodatek C, „Krótki opis deskryptorów DTD”. Przedstawia opis deskryptora Document Type Definition (Definicja Typu Dokumentu) web.xml. Nowość w drugim wydaniu.
· Dodatek D, „Kody stanu HTTP”. Lista kodów stanu określonych przez HTTP, a także stałe mnemoniczne wykorzystywane przez serwlety.
· Dodatek E, „Encje znakowe”. Lista encji znakowych zdefiniowanych w HTML, a także równoważne do nich wartości kodów ucieczkowych Uniksa.
· Dodatek F, „Kodowania”. Lista sugerowanych kodowań wykorzystywanych przez serwlety w celu tworzenia zawartości w różnych językach.
Proszę czuć się swobodnie i czytać rozdziały w niniejszej książce w dowolnej kolejności. Czytanie prosto od początku do końca zapewnia uniknięcie wszelkich niespodzianek, jako że starano się unikać odwołań do dalszych części książki. Przeskakiwanie jest jednak możliwe, zwłaszcza po rozdziale 5 — pozostała część rozdziałów została zaprojektowana w celu oddzielonego istnienia. Jedna ostatnia sugestia — proszę przeczytać podrozdział „Usuwanie błędów” w rozdziale 19, jeżeli kiedykolwiek napotka się fragment kodu pracujący nieprawidłowo.
Kursywa wykorzystywana jest do:
· Ścieżek, nazw plików i programów
· Nowych terminów podczas ich definiowania
· Adresów internetowych, takich jak nazwy domen i URL-e
Czcionka pogrubiona wykorzystywana jest do:
· Konkretnych klawiszy na klawiaturze
· Nazw przycisków interfejsu użytkownika i menu
Czcionka o stałej szerokości wykorzystywana jest do:
· Wszystkich danych pojawiających się dokładanie w programie Javy, takich jak słowa kluczowe, typy danych, stałe, nazwy metod, zmienne, nazwy klas oraz nazwy interfejsów
· Wszystkich wydruków kodu Javy
· Dokumentów HTML, znaczników i atrybutów
Czcionka o stałej szerokości z kursywą wykorzystywana jest do:
· Ogólnych obszarów zablokowanych wskazujących, że dany element jest zastępowany w programie przez konkretną wartość.
Pogrubiona czcionka o stałej szerokości wykorzystywana jest do:
· Wpisów w wierszu poleceń
Prosimy o pomoc w poprawieniu następnych wydań poprzez zgłaszanie wszystkich błędów, nieścisłości, niejasnych lub niewłaściwych wyrażeń oraz zwykłych literówek, które można odnaleźć w dowolnym miejscu niniejszej książki. Proszę wysyłać komunikaty o błędach i komentarze pod adres bookquestions@oreilly.com. (Przed wysłaniem komunikatu o błędzie prosimy sprawdzić erratę na stronie http://www.oreilly.com/catalog/jservlet2 w celu sprawdzenia, czy dany błąd nie został już opisany.)
Prosimy również o opinie, co powinno znaleźć się w tej książce, aby stała się ona bardziej przydatna. Wydawnictwo traktuje takie komentarze bardzo poważnie i próbuje dołączyć rozsądne sugestie do przyszłych wydań książki.
Kiedy pracowałem nad niniejszą książką, przyjaciel powiedział mi „Łatwiej musi być pisać drugie wydanie; napisałeś już raz tę książkę”. Pomyślałem nad tym przez chwilę, roześmiałem się i odpowiedziałem, „To jest łatwiejsze, ale ani trochę nie aż tak łatwe, jak się spodziewałem!”.
Patrząc wstecz, myślę że powód tego ma niewiele wspólnego z książkami, a bardziej z technologią. Pierwsze wydanie opisywało...
Ksiundz