Inspiracja , wiedza , realizacja
Jsystems

W przebudowie

Login



Java

Oracle

Linux

Android

PostgreSQL

Microsoft SQL Server

Spring MVC – pierwsza aplikacja – jak to wszystko działa

Data dodania: Jun 27, 2016
Data aktualizacji: Jun 27, 2016

Aplikacja jest tworzona w NetBeans, a uruchamiana na serwerze Glassfish który to jest dołączany do w.w. IDE.


Zaczniemy od stworzenia zwykłej aplikacji WEBowej:




Po jej utworzeniu musimy dodać niezbędne biblioteki. W Netbeans należy wybrać właściwości projektu, przejść do sekcji „Libraries” a następnie kliknąć AddLibrary i wybrać potrzebne:




Będzie nam też potrzebny plik konfiguracyjny web.xml, dlatego dodajemy do do katalogu WEB-INF:



Będzie nam też potrzebny jakiś pakiet w którym umieścimy nasze klasy:



Na początek aby przyjrzeć się sposobowi przekazywania kontroli nad wywołaniami Springowi, stworzymy zwyczajny serwlet. Pamiętaj by zaznaczyć dodanie informacji o nim do web.xml!




Gdy zajrzymy do web.xml po dodaniu serwletu, zobaczymy że pojawił się w nim taki oto wpis:




W liniach 7-9 mamy zapisane, że wywołanie podstrony „Przyklad.do” będzie obsługiwane przez nasz nowy serwlet. Nieco ten wpis przerobimy. Przyjrzyj się linii 9. Wpis „/” oznacza, że strona początkowa naszej aplikacji będzie obsługiwana przez nasz serwlet. Gdybyśmy wprowadzili tam wpis „/*” oznaczałoby to, że każde wywołanie adresu w naszej aplikacji będzie przez ten serwlet obsługiwane- tj. każdy podadres np. http://localhost:8080/SpringMVC/niematakiejstrony.do również byłoby obsłużone. Różnica w gwiazdce :)




Ważna informacja!!


Taki sposób deklaracji wzorca URL obsługiwanego przez Spring MVC sprawi, że również wszystkie statyczne zasoby będą obsługiwane przez Spring. To może uniemożliwić np. osadzenie plików obrazków czy PNG w aplikacji – te przecież nie będą obsługiwane przez żadne kontrolery. Bezpieczniej więc będzie użyć takiej konstrukcji:


<servlet-mapping>

<servlet-name>springmvc</servlet-name>

<url-pattern>*.do</url-pattern>

</servlet-mapping>


Dokonamy teraz małej zmiany w naszym serwlecie. W momencie wywołania naszej aplikacji na ekranie w przeglądarce powinna się wyświetlić treść „Halo, tutaj servlet!”.




Uruchommy więc naszą aplikację:




Moglibyśmy podzielić naszą aplikację na moduły i obsługiwać je przez różne serwlety... albo np. tylko jeden moduł obsługiwać z użyciem Spring MVC. Nieco przerabiam mój plik web.xml:




Porównajmy adres wywołania naszego serwletu:



Teraz będzie drobna zmiana. W linii 10 do adresu /jakismodul/ dodałem *. To oznacza że każde wywołanie z początkiem /jakismodul/ będzie obsługiwane przez nasz przykładowy serwlet:




I sprawdzamy :


Mam nadzieję, że po tych przykładach to co się dzieje w nowych liniach 14-21 w pliku web.xml będzie dla Ciebie oczywiste :) Wszystkie wywołania których adres będzie się zaczynał od /SpringMVC/spring/ będą obsługiwane przez serwlet o nazwie „springmvc”. A ten serwlet to klasa DispatcherServlet której.... nie definiowaliśmy :) To właśnie tutaj następuje przekazanie kontroli do Springa. To jest klasa dostarczana z bibioteką Springa, która przejmie kontrolę nad wywołaniami w naszej aplikacji (przynajmiej we wskazanym zakresie adresowym). Co by się stało gdybyśmy w linii 20 zdeklarowali „/*” ? Wszystkie wywołania w naszej aplikacji byłyby obsługiwane przez Springa..




OK, sprawdźmy teraz co się stanie kiedy wywołamy w przeglądarce adres nowego modułu:



Pojawił się błąd, a gdy mu się przyjrzymy zobaczymy że problem polega na braku pliku springmvc-servlet.xml To jest plik konfiguracyjny Spring MVC w którym będziemy deklarowali m.in. kontrolery naszej aplikacji. Nazwa pliku springmvc-servlet.xml nie jest przypadkowa. Wynika ona z tego jak nazwaliśmy servlet dla klasy DispatcherServlet w linii 15 pliku web.xml. Gdybyś w tym miejscu wpisał zamiast springmvc np. gdzieJestNemo, Spring szukałby pliku gdzieJestNemo-servlet.xml. Wielkość liter ma znaczenie.


Skoro Spring tak bardzo potrzebuje tego pliku, to mu go dajmy :




Nadamy mu nazwę springmvc-servlet.xml:




Będą nam też potrzebne pewne przestrzenie nazw XML które będziemy wykorzystywać, dlatego je zaznaczamy:




Nie ma możliwości wyboru przestrzeni MVC dlatego musimy dodać ją ręcznie do nowego pliku. Możesz tez gotowy plik pobrać z przykładowego kodu którego adres znajdziesz na początku tego rozdziału i umieścić go w katalogu WEB-INF.




Ponówmy próbę dostępu do modułu:



Zaglądamy do konsoli serwera:



Widzimy że Spring odnalazł nasz nowy plik (linia z Loading XML bean definitions....). Przyjrzyjmy się teraz ostatniej linii z ostrzeżeniem. Problem polega na tym, że nie określiliśmy w pliku springmvc-servlet.xml przez jaką klasę ma być obsługiwany adres /SpringMVC/spring/.


Dodajemy więc nowy wpis do springmvc-servlet.xml:




Linia 21 oznacza, że Spring ma poszukać deklaracji mapowań obsługiwanych adresów w adnotacjach znajdujących się w klasach pakietu (i jego podpakietów) który wskazaliśmy w linii 23 :)

Do pakietu pl.jsystems.springmvc.controller dodajemy teraz zwyczajną klasę Hello. Wprowadzamy metodę „sayHello” która wypisuje na konsoli serwera tekst „HELLO MUPPET”. Koniecznie dodaj wpis @Controller nad deklarają klasy, oraz @RequestMapping nad metodą SayHello.




Wpis @Controller z linii 16 deklaruje, że klasa ta obsługuje żądania HTTP, a @RequestMapping z parametrem wskazują która klasa do robi i dla jakiego konkretnie żądania. Adres /hello.do jest względny i oznacza wywołanie /SpringMVC/spring/hello.do.


Wywołajmy więc ten adres:



Nasze ulubione 404. Czy to znaczy że coś nie zadziałało? To zależy :) „This is not a bug, this is a feature” :) A tak poważnie – wszystko zgodnie z planem. Zajrzyjmy do konsoli serwera:



Wyświetlił nam się komunikat „Hello Muppet”, a to oznacza że nasza metoda sayHello została zgodnie z założeniem wywołana. Błąd 404 pojawia się dlatego, że nie mam strony JSP którą powinienem w odpowiedzi wyświetlić. Konkretnie to plik powinien się nazywać hello.jsp – ponieważ metoda sayHello zwraca ciąg tekstowy „hello” i powinien znajdować się bezpośrednio w katalogu WEB-INF co zdeklarujemy sobie w pliku springmvc-servlet:




W linii 27 deklaruję gdzie Spring ma szukać plików JSP, a w linii 28 jakie mają mieć rozszerzenie. Jeśli chcesz, w linii 27 możesz dodać jakiś podkatalog np. /WEB-INF/jsp/, albo wydzielić w ogóle osobny katalog na pliki jsp związane z tym modułem np. /WEB-INF/jsp/spring/


Stwórzmy jeszcze w zadeklarowanym katalogu plik hello.jsp:




i umieśćmy w nim taki oto kod:




Teraz przy wywołaniu adresu /SpringMVC/spring/hello.do powinniśmy zobaczyć taki komunikat:



Przydałoby się jednak zrobić coś więcej niż wyświetlanie statycznej wartości. Przekażmy więc jakieś dane z kontrolera do widoku (patrz linia 23):




a następnie wyświetlmy ją na stronie JSP (patrz linia 16):




Zauważ że w JSP odwołuję się do przekazanego elementu po nazwie która ustaliłem w pierwszym parametrze metody addAttribute tj. „wiadomosc”. Efekt:



Przekazywać oczywiście możemy też obiekty, listy, a także możemy obsługiwać formularze, ale tym zajmiemy się w kolejnych częściach tego kursu. W tej chwili zrobiliśmy chyba najprostszą możliwą implementację Spring MVC. Mamy oczywiście wiele możliwych wariantów – jak choćby w miejsce adnotacji użycie deklaracji beanów w pliku XML.


Jeszcze pozwolę sobie na małe rozwinięcie tematu zarządzania wywołaniami. Przypuśćmy że tworzymy dużą aplikację złożoną z kilku modułów i chcielibyśmy mieć osobne pliki konfiguracyjne. Kod źródłowy do następnych przykładów znajdziesz pod adresem :


http://www.jsystems.pl/storage/spring/springmvc2.zip


Dodamy sobie kolejną paczkę do web.xml:




W związku z tym że nasz serwlet nazywa się drugimodul dodajemy też plik „drugimodul-servlet.xml” . W nim dodajemy takie wpisy jak poprzednio, z tą różnicą że pliki JSP znajdą się w osobnym podkatalogu w WEB-INFie (patrz linia 27), a dodatkowo wydzielimy sobie osobny pakiet na kontrolery tego modułu. Dzięki temu będziemy mogli mieć klasy kontrolerów o takiej samej nazwie.




Oczywiście taki pakiet tworzymy, a w nim umieszczamy odrobinę różniącą się klasę kontrolera:




Zauważ że tutaj również określone jest mapowanie dla „/hello.do”, ale jak pamiętamy jest to adres względny i w tym przypadku oznacza wywołanie „/SpringMVC/drugimodul/hello.do”, a nie „/SpringMVC/spring/hello.do”. Metoda nadal zwraca tekst hello, co oznacza że Spring poszuka pliku hello.jsp by go wyświetlić, tym razem jednak będzie go szukał w katalogu „WEB-INF/drugimodul”.

W katalogu WEB-INF tworzymy podkatalog (taki jaki wskazaliśmy we wpisie w pliku drugimodul-servlet.xml) i umieszczamy w nim plik jsp analogiczny do poprzedniego, z tym że dla odróżnienia zmienimy troszkę jego zawartość.






Sprawdźmy: