Obsługa formularzy w Javie Web

Zajmiemy się teraz bardziej poważnym odbiorem danych od użytkownika. Wykonamy mianowicie aplikację pozwalającą na operacie CRUD na encji bazodanowej Country. Kraj posiada tylko swój idenyfikator, nazwę i id regionu, które jest oczywiście kluczem obcym. Po przygotowaniu sobie klasy DAO do encji Country przystępuję do pisania serwletów. Encja Country wygląda tak:

Być może zastanawiasz się dlaczego polem klasy Country jest obiekt Region, a nie regionID. Przy takim układzie mój obiekt Country będzie bardziej elastyczny. Mogę w nim zapisać zarówno samo id regionu, jak również całą strukturę Regionu – nazwę etc. Pierwszy serwlet będzie odpowiadał oczywiście za wyświetlenie danych w postaci tabeli:

Tym razem zdecydowałem się na konfigurację serwletu za pomocą adnotacji @WebServlet. W samym serwlecie nie dzieje się nic, czego byśmy wcześniej nie omawiali. Warstwa widoku jest podobnie prosta:

Dodałem od razu kolumnę Actions w której znajdują się dwa linki prowadzące do serwletu, który skasuje dany kraj i formularza z Edycją danego kraju. Muszę oczywiście podać informację o tym, na rzecz którego kraju ma zostać wywołana akcja. Dlatego przekazuję parametr id metodą GET (po linku).

Dołączyłem do powyższego przykładu bibliotekę CSS - Bootstrap, dlatego uzyskuję ładnie sformatowaną tabelkę:

Zajmiemy się teraz formularzem edycji. Najpierw tworzę serwlet, którego URL Pattern odpowiada temu z linka:

Zawartość parametru id oczywiście bierze się z adresu URL (np. editCountry.do?id=NL). Być może zastanawia Cię, po co przekazuję na widok również wszystkie regiony z bazy danych. Relacja między encją Region, a Country w bazie danych to jeden-wiele, dlatego jeden konkretny region, który przyporządkujemy do kraju – wybierzemy z selektora. Przystępuję do pisania formularza:

Wątpliwości mogą budzić dwie rzeczy. Po pierwsze nie określam atrybutu action tagu form, ponieważ będę przekazywał dane do tego samego URL. Po drugie – c:if w c:forEach. Spowoduje on automatyczne wybranie z listy regionu, do którego przypisany został kraj. OK. Zobaczmy jak to wygląda:

Pozostaje nam już tylko oprogramować metodę doPost() naszego serwletu. Na początek obejrzyjmy jakie informacje znajdują się w obiekcie HttpServletRequest.

Tak jak z request’a wyjmowaliśmy pojedynczy parametr – tak samo możemy wyjąć wszystkie w postaci mapy <String, String[]> po której zwyczajnie przeiterujemy.

Po zatwierdzeniu formularza uzyskuję w przeglądarce poniższy output:

Zauważ, że z poziomu metody doPost() mamy dostęp zarówno do parametrów przesłanych metodą GET jak i do tych przesłanych POST’em. Wystarczy, że z powyższych danych złożę obiekt i podam go warstwie DAO do zapisania w bazie:

OK. Tak to wygląda. Być może uważasz, że komplikuję sprawę ponad miarę try-catchem. Nie zapominaj jednak, że użytkownik może edytować źródło strony – a także o tym, że parametr ID jest przekazywany przez pasek. Temu właśnie służy try-catch – najpierw sprawdzam czy do edycji podano prawidłowe dane (czy to, co miało być liczbą rzeczywiście nią jest) , a także, czy referencje podane przez formularz (id regionu, id kraju) mają jakieś odzwierciedlenie w bazie danych. Dopiero po spełnieniu tych dwóch warunków przystępuję do złożenia obiektu Country, zapisania go w bazie danych i poinformowania formularza, że edycja przebiegła pomyślnie. Dodatkowo w widoku dodaję nad polami formularza poniższy wpis:

Jest to wyświetlenie informacji o poprawnej edycji (w języku EL sprawdzenie czy jakiś atrybut został przekazany realizujemy instrukcją not empty). Po poprawnej edycji jakiegoś kraju dostanę oczywiście powiadomienie:

Wszystko działa dokładnie tak jak chcieliśmy. Oczywiście przydałaby się jeszcze jakaś walidacja danych, ale nie robiłem tego aby nie zaburzać czytelności przykładu. Podpowiem tylko, że walidację danych najlepiej wydzielić do oddzielnej metody przyjmującej jakiś obiekt i ew. wpisującej błędy do mapy, do której później odwołamy się za pomocą EL.

Ten artykuł jest elementem poniższych kursów: