#08 – aplikacje webowe

By 4 października 2014Kurs Javy
unnamed (1)

W dzisiejszej lekcji nauczymy się co nieco o aplikacjach webowych, które stanowią zdecydowaną większość tworzonych współcześnie aplikacji.

Wiedza jak pisać aplikacje webowe jest w dzisiejszych czasach kluczowa dla pracodawców. Jak się sama przekonasz, nie różnią się one tak bardzo od zwykłych aplikacji, a biblioteka Spring MVC tylko uprości nam zadanie.

Lekcja

Choć lekcja ta będzie poświęcona aplikacjom webowym, nie będziemy tutaj poznawać API Javy EE. Oczywiście polecam samodzielnie poczytać na ten temat, rozszerzyć sobie wiedzę o Servletach itp., ale prawda jest taka że z ‚czystego’ API korzysta się niezwykle rzadko. Precyzyjna wiedza na ten temat oczywiście przydaje się, ale nie jest konieczna do rozpoczęcia kariery w IT.

Ale na pewno musimy sobie wyjaśnić czym właściwie jest Java EE :) Mówiąc najogólniej, jest to zbiór kontraktów (w postaci najczęściej interfejsów), czyli ustaleń, że pewne rzeczy mają działać tak, a nie inaczej. Dzięki temu aplikacje webowe możemy rozdzielić na dwa zasadnicze elementy – serwer aplikacji oraz samą aplikację (w postaci pliku WAR). Jeśli nasza aplikacja korzysta tylko ze standardowych elementów (ze specyfikacji Java EE), to możemy ją uruchomić (zdeployować, zrobić deploy) na dowolnym serwerze aplikacji.

Z czego składają się aplikacje webowe

Działająca aplikacja webowa (tj. taka, która działa na serwerze i jest dostępna dla użytkowników) w technologii Java EE tak jak wspominałem wcześniej składa się z 2 podstawowych elementów: serwera aplikacji oraz pliku WAR (często ten plik nazywany jest aplikacją webową, bywa też określany mianem modułu, systemu itp. – nie ma tutaj bardzo ścisłych określeń).

Uwaga: to nie jest do końca prawda, ponieważ można dołączyć lekki kontener, np. Jetty, do samego pliku WAR przez co nie potrzebuje on serwera aplikacji. Ma to swoje zalety, w takiej sytuacji serwer aplikacji (najczęściej zubożony) jest niejako częścią samej aplikacji, więc fizycznie nie ma podziału na 2 części, ale logicznie można nadal wyróżnić oba elementy.

Serwer aplikacji

Serwer aplikacji to ‚część wspólna’ wszystkich aplikacji webowych, która zapewnia nam podstawowe mechanizmy (np. zarządzanie wątkami, możliwość dynamicznego ładowania aplikacji, autoryzację i uwierzytelnianie (JAAS), obsługę protokołu HTTP, szyfrowanie o obsługę SSL oraz inne elementy z których możemy korzystać za pomocą określonych API). Na rynku jest wiele serwerów aplikacji, natomiast my będziemy wykorzystywali Tomcat jako jeden z prostszych i dzięki temu działających sprawnie także na komputerze lokalnym. Z najbardziej popularnych możemy wyróżnić:

  • Tomcat (bezpłatny) – technicznie nie jest to serwer aplikacji, ale na potrzeby kursu jest wystarczający
  • Glassfish (bezpłatny, istnieje opcja płatna)
  • JBoss AS (bezpłatny, istnieje opcja płatna)
  • WebSphere (płatny)
  • WebLogic (płatny)

Serwery aplikacji mogą mieć uruchomione wiele aplikacji jednocześnie, które są rozróżniane za pomocą tzw. kontekstów. Załóżmy, że nasz serwer jest uruchomiony na naszym komputerze (który ma zawsze adres localhost) i działa na domyślnym porcie aplikacji webowych w Javie (8080). Adres http://localhost:8080/kontekst1/cos spowoduje, że zostanie uruchomiona aplikacja przypisana do kontekstu o nazwie kontekst1, a w ramach tej aplikacji zostanie obsłużony adres /cos . Nazwa kontekstu nadawana jest najczęściej automatycznie na podstawie nazwy pliku WAR (np. plik aplikacja.war będzie miał kontekst o nazwie aplikacja, a plik cos.war będzie miał kontekst o nazwie cos ).

Aby uruchomić plik WAR na serwerze aplikacji, najczęściej wystarczy umieścić go w odpowiednim katalogu. W przypadku serwera Tomcat (na którym będziemy pracowali i pokazywali przykłady) jest to katalog /webapps , w przypadku np. JBossa (z którego bardzo często korzysta się w przypadku aplikacji produkcyjnych) jest to katalog /deployments . W przypadku innych serwerów, stosowna informacja powinna być w dokumentacji dostarczonej przez autorów.

Plik WAR

Pliki WAR to nic innego jak określona struktura katalogów spakowana jako zip. Bardziej szczegółowo strukturę omówimy sobie poniżej. To co powinniśmy wiedzieć to to, że plik WAR powinien być kompletną aplikacją/modułem, tzn powinien zawierać nasz kod oraz wszystkie zależności (biblioteki, zewnętrzne moduły itp), które są potrzebne w naszej aplikacji.

Struktura aplikacji webowej (pliku WAR)

Tak jak wspomniałem wcześniej, plik WAR to spakowana struktura katalogów i specyficzne pliki. Przyjrzyjmy się bliżej najważniejszym katalogom i plikom.

  • / – katalog główny, pliki w tym katalogu są dostępne publicznie, należy więc uważać, żeby nie umieścić tam żadnych wrażliwych danych, np. danych dostępowych do bazy danych itp. Wyjątkiem są katalogi WEB-INF oraz META-INF. W tym katalogu umieszczamy treści takie jak pliki jsp (nie będziemy z nich korzystać w taki sposób), grafiki używane w interfejsie, skrypty JS, arkusze styli CSS itp. Zawartość tego katalogu jest reprezentowana w naszym projekcie Mavenowym poprzez katalog /src/main/webapp
  • /WEB-INF – to katalog, w którym jest nasz skompilowany kod, a także zawartość katalogu /src/main/resources z naszego projektu Mavenowego. Poza tym wewnątrz znajdziemy:
    • web.xml – główny (i tak naprawdę jedyny wymagany) plik aplikacji webowej, określony w standardzie JavaEE. Definiujemy w nim Servlety, Listenery, Filtry itp. My będziemy go używać tylko po to, żeby uruchomić Springa -w skrócie, powiemy, że wszystkie zapytania mają być obsługiwane przez Servlet dostarczany przez Springa, oraz wskażemy gdzie znajduje się nasza konfiguracja
    • classes – skompilowane nasze klasy
    • lib – biblioteki i zależności w postaci plików JAR (np. tutaj znajdziemy biblioteki Springa)
  • /META-INF – w tym katalogu najczęściej znajdziemy pliki których sami tam nie umieszczaliśmy ;) Biblioteki czasem przechowują tutaj konfigurację, deskryptory, opisy itp. Na tą chwilę nie będziemy się nim zajmować.

MVC

Zanim przejdziemy do Springa powiemy sobie parę słów czym właściwie jest MVC. To akronim od Model – View – Controller, co symbolizuje ‚trójpodział’ aplikacji. Idea jest prostsza niż to brzmi ;) Chodzi o to że pisząc funkcjonalność (np. wypisywanie listy kotów w naszej aplikacji) wyróżniamy trzy jej rozdzielne elementy:

  • model – czyli tzw. domenę, są to obiekty które reprezentują pewien fragment rzeczywistości (np. w naszej aplikacji takim obiektem jest Kot) oraz powiązane elementy (np. kod zapisujący/odczytujący dane naszych kotów z bazy danych)
  • view – widoki to to, co widzi użytkownik. Są to najczęściej fragmenty kodu HTML wzbogacone o dodatkowe elementy języka (np. żeby wyświetlić dynamiczne informacje)
  • controller – to tzw. kontrolery, czyli logika, która stoi za naszymi stronami – innymi słowy kod który łączy model (bazę danych) z widokami (użytkownikiem).

Tutaj uwaga! W aplikacjach często używa się tzw. serwisów (czyli klas, które oferują funkcjonalność czysto biznesową, np. wyślij emaila, wywołaj jakiś inny program). Serwisy są wywoływane przez kontrolery i w zależności od podejścia mogą być uwzględniane w pojęciu ‚kontrolery’ lub nie – to zależy tak naprawdę od przyjętej nomenklatury.

W naszym przypadku będziemy wykorzystywać SpringMVC który pomaga nam połączyć powyższe elementy w jedną całość i ograniczyć ilość pisanego kodu ‚boilerplate’ (to kod, który nie realizuje stricte funkcjonalności, a służy jedynie temu, żeby całość mogła działać ze sobą – przykładem są np. gettery i settery).

Poniższy diagram obrazuje zależności i sposób interakcji pomiędzy tymi komponentami:

Zależności pomiędzy elementami MVC. Źródło: Schemat interakcji pomiędzy poszczególnymi elementami we wzorcu MVC.  Źródło: WIKIPEDIA

Spring MVC

Od razu zastrzegam że to, jak używać SpringMVC omówimy w kolejnej lekcji, dzisiaj będzie tylko koncepcja oraz kilka informacji :)

Przede wszystkim, czym jest i co nam daje: Spring Framework to obecnie najpopularniejszy framework do tworzenia aplikacji w języku Java. Do jego sukcesu przyczyniła się przede wszystkim elastyczność – można go stosować niemalże w każdym rodzaju aplikacji, a jednocześnie precyzyjnie konfigurować jego działanie. Framework ten zbudowany jest wokół zasady convention-over-configuration, tzn. nie musimy nic konfigurować i wtedy zostaną przyjęte sensowne wartości domyślne. Najczęściej jest to super rozwiązanie, pozwalające znacznie ograniczyć ilość pracy przy projekcie. Od jakiegoś czasu głównym sposobem na ‚współprace’ ze Springiem są adnotacje, czyli np. @Component nad nazwą klasy (adnotacje omówimy w kolejnej lekcji).

To, co daje nam Spring to przede wszystkim kontener IoC (Inversion of Control) – oznacza to w uproszczeniu (i nie do końca w zgodzie z rzeczywistością – ale na potrzeby kursu możemy przyjąć że tak jest) że w przeciwieństwie do ‚standardowej’ sytuacji, w której to klasa sama musi zadbać o inicjowanie potrzebnych jej komponentów, to kontener dba o tworzenie odpowiednich obiektów i ich ‚wstrzykiwanie’ (tzw. DI – Dependency Injection, to jedna z cech kontenera IoC), czyli ustawianie odpowiednich pól klasy właściwymi wartościami.

Spring MVC to ‚rozszerzenie’ Frameworka Spring o wsparcie dla aplikacji webowych (m.in obsługa adresów URL, przesyłania danych poprzez formularze itp) dzięki czemu tworzenie aplikacji webowej jest prostsze niż kiedykolwiek.

W przypadku Spring MVC spotkamy się też z pojęciem tzw. view resolvera – to specjalna klasa, która otrzymuje nazwę widoku do wyświetlenia oraz dane które przekazujemy do tego widoku (obiekt typu ModelAndView) i na tej podstawie generuje widok, który widzi użytkownik. Omówimy to od strony praktycznej poznając kontrolery.

To co jeszcze należy wiedzieć o Springu to kilka pojęć:

  • bean – to obiekt dowolnego typu, który jest zarządzany przez Spring’a a tym samym podlega wstrzykiwaniu (czyli można go wstrzyknąć w dowolny obiekt z użyciem adnotacji)
  • komponent / stereotyp – to adnotacja, która mówi że obiekt danej klasy ma być zarządzany przez Springa (innymi słowy: mówimy Springowi żeby utworzył beana o takim typie)
  • component-scan – procedura, którą Spring wykonuje na początku (podczas inicjowania aplikacji) i która polega na ‚przejrzeniu’ wszystkich dostępnych oraz znalezieniu tych, które są oznaczone jako komponenty (mają określony stereotyp)
  • view resolver – patrz wyżej ;)

To tyle teorii, do praktyki przejdziemy w kolejnej lekcji :)

Materiały dodatkowe / dokumentacja

  1. Opis pliku web.xml i możliwości jego konfiguracji (EN)
  2. Opis pliku WAR (EN)
  3. Reference do SpringMVC (EN)
  4. Szybki tutorial Spring MVC (EN) – spoiler! to będziemy omawiać w kolejnej lekcji dokładniej

Zadanie

Dzisiejsze zadanie praktyczne będzie dość proste:

  • dodaj do projektu Maven moduł koty-webapp (tak, aby był typu WAR)
  • do projektu koty-webapp dodaj zależności koty-domain oraz koty-application (pamiętaj, że zależności są przechodnie – więc wystarczy dodać tylko jedną z nich (wiesz którą, prawda? :) ) a druga będzie ‚w komplecie’ – jako zależność zależności
  • do projektu koty-webapp dodaj zależności do spring MVC oraz Spring context w tych samych wersjach, co spring-core

Dodatkowo polecam zapoznać się z tutorialami Spring MVC lub oficjalnym getting started – ułatwi to następną lekcję :)

UWAGA!! Rozwiązanie tego zadania nie jest jeszcze pełnoprawną aplikacją webową! Brakuje przede wszystkim pliku web.xml, który jest niezbędny do uruchomienia aplikacji na serwerze. Plik ten dodajemy dopiero w lekcji 9. Poniższego rozwiązania NIE DA SIĘ uruchomić bez modyfikacji.

zip Pobierz rozwiązanie tego zadania

Licencja Creative Commons

Jeśli uważasz powyższą lekcję za przydatną, mamy małą prośbę: polub nasz fanpage. Dzięki temu będziesz zawsze na bieżąco z nowymi treściami na blogu ( i oczywiście, z nowymi częściami kursu Javy). Dzięki!

  •  
  •  
  •  
  •  
  •  
  • pioiop

    „dodaj do pro­jektu Maven moduł koty-webapp”

    po raz kolejny nie czaje określenia moduł… może ktoś wytłumaczyć na czym polega ten krok?

    • Cześć,

      zajrzyj do poprzedniej lekcji, którą uzupełniliśmy :) Odpowiednie informacje znajdziesz pod nagłówkiem ‚Pro­jekty i mod­uły w Mavenie’

      Pozdrawiamy!

  • ktosiek

    Czy można prosić o udostępnienie rozwiązania? Podany link nie działa :)

  • Adrian

    Nie wiem co jest źle,nawet po pobraniu dostępnego rozwiązania dostaje błąd „Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project koty-webapp: Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode)” Możecie mi pomóc ?

    • jachu

      Mam podobny problem tj.
      „web.xml is missing and is set to true pom.xml /koty-webapp line 39 Maven Java EE Configuration Problem”

      U siebie, ani w załączonym do zadania rozwiązaniu nie widzę /WEB-INF i web.xml.

      W pom’ie parenta mam ustawione pom.
      A w pom’ie koty-webapp mam ustawione war

      • Cześć, odpowiedź do tego zadania nie ma się uruchamiać na serwerze! dopiero w lekcji 9 (http://kobietydokodu.pl/09-spring-mvc/) dodajemy niezbędne elementy, które pozwolą nam uruchomić projekt jako aplikację webową.

      • jachu

        Już sobie pomogłem.
        Znalazłem wskazówki w kolejnej tj 09 lekcji :)

  • kux

    Ktoś kojarzy dlaczego Maven chce korzystać z 1.5?
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile (default-compile) on project koty-application: Compilation failure
    [ERROR] C:UsersXworkspaceKotykoty-applicationsrcmainjavaorgkotyapplicationInterfejs.java:[14,11] error: strings in switch are not supported in -source 1.5

  • test

    convention-over-configuration serio? A mi się wydaje, że tu trzeba mnóstwo konfigurować w porównaniu z ASP.NET MVC, django, ror itp

    • To zależy jak rozumiemy CoC – wydaje mi się, że nie chodzi o to, że nie ma być konfiguracji wcale, a jedynie to, że w przeważającej ilości przypadków możesz polegać na domyślnej konfiguracji. Wspomniane przez Ciebie technologie może faktycznie wymagają mniej konfiguracji ale z drugiej strony mogą być mniej elastyczne. Biorąc pod uwagę ilość rzeczy, które można skonfigurować, vs ilość rzeczy które trzeba skonfigurować, Java wypada naprawdę nieźle ;) Aczkolwiek nie zrozum mnie źle – nie twierdze, że nie ma bardziej ‚CoC’ technologii. Pewnie są. Ale Java + Spring z pewnością może używać tego określenia bez kompleksów.

  • Ania

    Przepraszam…ale nie rozumiem tego dodawania modułów. Już nawet się zgubiłam w której części to było. Po co dodaje się 3 moduły (koty-application, koty-domain i koty-webapp) ? Wszystkie te 3 foldery są potrzebne do uruchomienia aplikacji? Wszystkie muszą mieć pom.xml? Sam folder koty-webapp nie wystarczy? Do utowrzenia zwykłego widoku?

    • Oczywiście można wszystkie pliki umieścić w jednym module i jak najbardziej aplikacja zaprojektowana w ten sposób będzie działała. Powód, dla którego dzielimy to na 3 osobne moduły (z których każdy ma swój własny plik pom.xml) jest taki, że w ten sposób dzieli się aplikacje – dzięki temu moduły mogą być wykorzystywane w wielu projektach i łatwiej też ‚ogarniać’ mniejsze części aplikani i pracować nad nimi zespołami. Dlatego staramy się nie tylko pokazać jak uruchomić aplikację w wersji minimalnej, ale także przygotować do pracy w przyszłości.

  • Krzyś miś

    Tomcat obok Glassfisha, Jbossa i Weblogic? Tomcat to kontener, a nie pełnoprawny serwer aplikacyjny…

    • To prawda, jednak z punktu widzenia kursu i wykorzystywanych technologii, nie ma to dużego znaczenia – Tomcat także spełnia nasze potrzeby. Dla wyjaśnienia dodaliśmy stosowną informację do lekcji

  • Damian Nowak

    No nie powiem ale ten blog jest świetny, przede wszystkim wizualnie jest to ładnie urządzone a dodatkowo treści są zwięzłe i tematycznie dobrze dopasowane. Piona! ;-)

  • PrzypadkowyGość

    Zacznę od tego, że blog jest świetnie wykonany i śmiało mogę powiedzieć, że trafia do mojego top3.
    Jako, że od niedawna piszę w Javie SE i mam zamiar powoli przejść do JEE i JSP, to zapytam czy ten blog też jest tworzony w jakichś technologiach Javowych? Mam tu na myśli właśnie np JSP, Spring itd.

    • Dzięki ;) Cieszymy się, że możemy pomóc w rozwijaniu pasji do programowania!

      Co do bloga – jest on postawiony na WordPressie z przyczyn czysto wygody – WordPress jest bardzo potężną platformą do tworzenia treści, o ile w Javie są alternatywy o podobnych i większych możliwościach (patrz np. Liferay), to nie są one tak popularne w kontekście pluginów i szablonów graficznych. Oczywiście moglibyśmy stworzyć sami to, czego potrzebujemy ale trochę nam szkoda na to czasu ;)

  • Przemko

    Albo źle coś czytam, albo tego nie widzę. Ale co to są te moduły i jak się je tworzy? Mógłby mi to ktoś jakoś zobrazować bo kompletnie nie ogarnia tego….