PAŃSTWOWA WYŻSZA SZKOŁA ZAWODOWA W TARNOWIE INSTYTUT POLITECHNICZNY SPECJALNOŚĆ: INFORMATYKA PRACA DYPLOMOWA TEMAT: Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT z wykorzystaniem technologii JAVA i PostgreSQL Promotor: Dr inż. Robert Wielgat Autorzy: Tarnów 2008
2 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Podziękowania Dziękujemy kaczorom, Donaldom i innym bez których nie znaleźlibyśmy odpowiedniej motywacji do napisania tych podziękowań przykładowych bezsensownie zajmujących przestrzeń tekstową w tymże obszarze
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 3 Spis treści 1 Wstęp... 5 2 Cele pracy... 6 3 Narzędzia oraz technologie wykorzystane w aplikacji... 7 3.1 HTML... 7 3.2 CSS... 8 3.3 PostgreSQL... 10 3.4 Java... 11 3.4.1 JavaServer Pages... 11 3.4.2 Spring Framework... 12 3.5 Serwer Apache Tomcat... 15 4 Struktura programu...16 4.1 Aplikacje webowe wykonane w technologii Java Servlet... 16 4.2 Środowisko programistyczne... 20 4.3 Szkielet aplikacji... 21 4.4 Warstwa prezentacji... 23 4.5 Warstwa DAO... 24 4.6 Diagram relacji w bazie danych... 29 4.7 Przepływ sterowania w aplikacji... 30 4.8 Mapowanie odpowiednich adresów URL na kontrolery... 31 4.9 Dispacher-servlet... 33 4.10 Kontrolery oraz wzorce projektowe command oraz Application-controller.... 37 4.11 Obsługa żądań... 39 4.12 Nowe typy odpowiedzi... 43 5 Funkcjonalny opis aplikacji...45 5.1 Zakładka kolokwia... 47 5.1.1 Wyświetlanie listy wszystkich kolokwiów... 47 5.1.2 Skala ocen... 48 5.1.3 Dodawanie nowych wzorów... 48 5.1.4 Utworzenie nowego kolokwium... 48 5.2 Zakładka Pytania... 57 5.2.1 Wyświetlanie listy pytań... 57
4 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 5.2.2 Dodanie nowego pytania... 57 5.3 Zakładka Studenci... 59 5.3.1 Wyświetlanie listy roczników... 59 5.3.2 Rozkład zajęć... 59 5.3.3 Klonowanie sal... 59 5.4 Zakładka Plan zajęć... 61 5.4.1 Lista planów nauczania... 61 5.4.2 Cele nauczania... 64 5.4.3 Instrukcje... 66 6 Podsumowanie...68 7 Bibliografia...69
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 5 1 Wstęp W ciągu całego toku nauczania na Państwowej Wyższej Szkole Zawodowej w Tarnowie, na szóstym semestrze odbywały się zajęcia z Technik Multimedialnych. Na laboratoriach z tego przedmiotu wykorzystywana jest aplikacja TMT (Tarnów Multimedia Toolbox). Wedle opinii osób z naszego roku idea prowadzenia zajęć w ten właśnie sposób jest bardzo trafna i godna poświęcenia uwagi oraz pracy. Można się pokusić o stwierdzenie, iż jest to przyszłość w prowadzeniu zajęć, bowiem powszechnie wiadomo, że obraz ruchomy z odpowiednią narracją jest najłatwiejszym do przyswojenia medium przekazu. Teraz gdy programowanie w Internecie jest w dużym stopniu ułatwione przez technologie typu Java, PHP, HTML, Flash, programiści mogą się wykazać jeśli chodzi tego typu zagadnienia. Co lepsze, pozostawia to całą gamę możliwości dalszej rozbudowy przez naszych następców. Przy odpowiednim nakładzie pracy wierzymy, wierzymy mocno iż projekt tej aplikacji będzie nieodzowną pomocą oraz ułatwieniem dla studentów jak i wykładowców z niej korzystających w chwili obecnej jak i w przyszłości.
6 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 2 Cele pracy Naszym zadaniem było rozbudowanie oraz poprawa zarówno wyglądu jak i funkcjonalności aplikacji TMT.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 7 3 Narzędzia oraz technologie wykorzystane w aplikacji 3.1 HTML HTML (ang. Hyper Text Markup Language, pol. hipertekstowy język znaczników) to dominujący język wykorzystywany do tworzenia stron internetowych. Pozwala opisać strukturę zawartych w dokumencie nadając znaczenie poszczególnym fragmentom tekstu (formując linki, nagłówki, akapity, listy, itp.) oraz osadzić w tekście dodatkowe obiekty np. statyczne grafiki, interaktywne formularze, dynamiczne animacje. W składni języka HTML wykorzystuje się znaczniki opatrzone z obu stron nawiasami ostrokątnymi. Język HTML umożliwia, do pewnego stopnia, zdefiniowanie sposobu wizualnej prezentacji dokumentu w przeglądarce internetowej, a także osadzenie ciągów instrukcji języków skryptowych, wpływających na zachowanie przeglądarek lub innych parserów HTML. Zaleca się zrezygnowanie z wykorzystywania znaczników opisujących wygląd strony na rzecz kaskadowych arkuszy stylów CSS. Ważną cechą języka, która wyraźnie przyczyniła się do rozpowszechnienia sieci WWW jest niezależność od systemu operacyjnego oraz parametrów sprzętowych komputera, na którym strony te będą oglądane. HTML definiuje kilka typów danych, wprowadzanych jako wartości elementów lub atrybutów. Są to m.in. skrypty (script data), dane arkuszy stylów (stylesheet data), identyfikatory, nazwy, adresy URL, liczby, jednostki miary długości, języki, deskryptory mediów, kolory, kodowania znaków, data i czas, itp. Język HTML składa się z kilku kluczowych komponentów: znaczników (i ich atrybutów), typów danych, referencji znakowych, odwołań w postaci encji, deklaracji typu dokumentu.
8 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 3.2 CSS CSS (ang. Cascading Style Sheets, pol. Kaskadowe arkusze stylów) to język służący do opisu formy prezentacji (wyświetlania) stron WWW. CSS został opracowany przez organizację W3C w 1996 r. jako potomek języka DSSSL przeznaczony do używania w połączeniu z SGML-em. Pierwszy szkic CSS zaproponował w 1994 r. Hakon Wium Lie. Arkusz stylów CSS to lista dyrektyw (tzw. Reguł) ustalających w jaki sposób ma zostać wyświetlana przez przeglądarkę internetową zawartość wybranego elementu (lub elementów) (X)HTML lub XML. Można w ten sposób opisać wszystkie pojęcia odpowiedzialne za prezentację elementów dokumentów internetowych, takie jak rodzina czcionek, kolor tekstu, marginesy, odstęp międzywierszowy lub nawet pozycja danego elementu względem innych elementów bądź okna przeglądarki. Wykorzystanie arkuszy stylów daje znacznie większe możliwości pozycjonowania elementów na stronie, niż oferuje sam (X)HTML. CSS został stworzony w celu odseparowania struktury dokumentu od formy jego prezentacji. Separacja ta zwiększa zakres dostępności witryny, zmniejsza zawiłość dokumentu, ułatwia wprowadzenie zmian w strukturze dokumentu. CSS ułatwia także zmienianie renderowania strony w zależności od obsługiwanego medium (ekran, palmtop, dokument w druku, czytnik ekranowy). Stosowanie zewnętrznych arkuszy CSS daje możliwość zmiany wyglądu wielu stron na raz bez ingerowania w sam kod (X)HTML, ponieważ arkusze mogą być wspólne dla wielu dokumentów. Nazwa kaskadowe arkusze stylów wynika z faktu, iż gdy reguły CSS wykluczają się wzajemnie w arkuszu zewnętrznym, arkuszu wewnętrznym oraz na poziomie elementów HTML, priorytet stylów ustalany jest hierarchicznie. Przyjęto, że oddziaływanie stylów z arkuszy zewnętrznych może być modyfikowane przez style zdefiniowane bliżej formatowanego elementu. Kolejność interpretacji reguł formatujących dany element przez przeglądarkę przedstawia się następująco: Domyślny arkusz przeglądarki WWW (niezależny od autora strony) Domyślny arkusz użytkownika przeglądarki (jak wyżej)
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 9 Zewnętrzne arkusze stylów Definicje stylów w nagłówku dokumentu Definicje stylów w atrybucie style elementu Ten model działania pokazuję, w jaki sposób działa kaskada stylów. Między stylami z różnych źródeł nie muszą zresztą wcale występować żadne konflikty, tworzą one jeden wielki styl.
10 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 3.3 PostgreSQL PostgreSQL to obok MySQL oraz FIrebird, jeden z trzech najpopularniejszych wolnodostępnych systemów zarządzania relacyjnymi bazami danych. Początkowo opracowywany na Uniwersytecie Kalifornijskim w Berkeley i opublikowany pod nazwą Postgres. W miarę rozwoju i zwiększania funkcjonalności, baza danych otrzymała nazwy Postgtres95 i ostatecznie PostgreSQL, aby upamiętnić pierwowzór oraz zaznaczyć zgodność ze standardem SQL. PostgreSQL ma zaimplementowany mechanizm MVCC (Multiversion Concurency Control) do zarządzania transakcjami. Mechanizm ten umożliwia udostępnienie tej samej krotki więcej niż jednej transakcji. Równocześnie może istnieć przynajmniej kilka wersji tej samej krotki, które nie są widoczne dla innych użytkowników do zakończenia danych transakcji. Dzięki temu baza danych wydajnie zachowuje zasadę ACID. Można tworzyć większość obiektów bazodanowych m.in.: Indeksy, Operatory, Agregaty, Domeny, Rzutowania, Konwersje. Silnik ten zawiera wiele obiektowych rozszerzeń takich jak możliwość definiowania nowych typów podstawowych i dziedziczenia typów tablic. Posiada zaawansowany system transakcji, dwufazowe zatwierdzanie (2PC) i możliwość dodawania funkcjonalności dzięki modułom zawartym w contribie. Jednym z pierwszorzędnych celów twórców PostgreSQL jest jak największa zgodność ze standardem SQL.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 11 3.4 Java Java jest obiektowym językiem programowania stworzonym przez grupę roboczą pod kierunkiem Jamesa Goslinga z firmy Sun Microsystems. Java jest językiem tworzenia programów źródłowych kompilowanych do kodu bajtowego, czyli postaci wykorzystywanej przez maszynę wirtualną. Język cechuje się silnym typowaniem. Jego podstawowe koncepcje zostały przejęte z języka Smalltalk (maszyna wirtualna, garbage collection) oraz z języka C++ (duża część składni i słów kluczowych). 3.4.1 JavaServer Pages JavaServer Pages to technologia umożliwiająca tworzenie dynamicznych dokumentów WWW w formatach HTML, XHTML, DHTML oraz XML z wykorzystaniem języka Java, wplecionego w kod HTML danej strony. W tym aspekcie, jest to rozwiązanie podobne do PHP. Jest to odmiana serwletów (aplikacji w Javie uruchamianych po stronie serwera). Przy wywołaniu, strona JSP zamieniana jest na servlet, który wykonuje właściwe działanie i każde kolejne zapytania do tej strony. Jeśli użyta zostanie prekompilacja (kompilacja wstępna) to już podczas uruchamiania aplikacji wszystkie strony JSP zostaną przetłumaczone na servlety. Strony JSP składają się z następujących elementów: Treść statyczna przepisywana bez modyfikacji do generowanego dokumentu, Dyrektywy JSP informacje kontrolujące proces generowania dokumentu, Elementy skryptowe skrypty (kod w języku Java kontrolujący proces generowania dokumentu) oraz elementy składniowe tzw. Expression Language, Akcje JSP tagi XML wywołujące określone metody serwerowe.
12 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 3.4.2 Spring Framework Spring jest szkieletem tworzenia aplikacji w języku Java dla platformy J2EE (jakkolwiek istnieje też wersja dla środowiska.net). Spring powstał na bazie kodu opublikowanego w książce Roda Johnsona Design and Development. Pozytywny odzew czytelników sprawił, że był on dalej rozwijany przez autorów (m.in. Johnsona, Jurgena Hoellera), którzy postanowili założyć firmę Interface21, świadczącą usługi konsultingowe związane z tym szablonem. Pierwsze wydanie springa pojawiło się w lipcu 2003 roku na bazie licencji Apache 2.0 licence. Wersja 1.0 ukazała się w marcu 2004 roku. Spring powstał jako alternatywa dla programowania aplikacji z użyciem Enterprise JavaBeans. Programowanie z użyciem EJB narzucało wiele innych ograniczeń, wymagając między innymi przyjęcie określonego modelu tworzenia oprogramowania. Funkcjonalność EJB okazała się także za ciężka do wszystkich zastosowań (w małych projektach wykorzystywano tylko niewielką część oferowanej przez EJB funkcjonalności jednocześnie stworzenie małej aplikacji w środowisku EJB wymagało nakładu pracy jak przy aplikacji dużej). Odmienna koncepcja Springa lekkiego szablonu, który nie wymusza specyficznego modelu programowania stała się bardzo popularna wśród programistów Javy. Spring oferuje dużą swobodę w tworzeniu rozwiązań a jednocześnie jest dobrze udokumentowany i zawiera rozwiązania wielu często występujących zagadnień w programowaniu. Podczas gdy bazowe komponenty Springa mogą być używane praktycznie w każdej aplikacji istnieje w nim wiele rozszerzeń, które pozwalają budować aplikacje webowe na bazie J2EE. 3.4.2.1 Odwrócenie sterowania kontener IoC Spring zapewnia bazowane na JavaBeans ach zarządzanie konfiguracją, stosowanie zasad odwrócenia sterowania (ang. Inversion-of-control, IoC). Pozwala to na szybsze i prostsze składanie aplikacji. IoC kojarzone jest także ze Wstrzykiwaniem
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 13 zależności (ang. Dependency Injection), jakkolwiek to drugie jest pojęciem węższym. Zasady IoC używane są w Springu jako technika, która pozwala przekazać na zewnątrz (ang. externalize) tworzenie i zarządzanie zależnościami pomiędzy komponentami programu zależności konfigurowane są w pliku, a zarządzanie wykonywane jest przez kontener IoC.
14 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 3.4.2.2 Szablon dostępu do danych DAO Warstwa abstrakcji JDBC, opakowuje standardowy mechanizm JDBC rzucając znaczące wyjątki zorganizowane w hierarchię (nie ma potrzeby wyciągania kodów dostawcy z wyjątku SQLExeption). Podejście to znacznie redukuje ilość kodu, którą musi napisać programista, aby obsłużyć błędy. Nie ma potrzeby pisania kolejnych bloków finally. Wyjątki związane z JDBC są zgodne z hierarchią wyjątków generycznego obiektu dostępu do danych (DAO) w Springu. Ta sama warstwa abstrakcji pozwala integrować aplikację z Hibernate, Java Data Objects oraz mapami SQL ibatis a, a w sensie uchwytów do zasobów, wsparcia dla obiektów dostępu do danych i strategii transakcji. bardzo silne wsparcie dla Hibernate z mnóstwem udogodnień IoC, które wspomagają typowe zagadnienia integracji Hibernate z aplikacjami. Wszystkie one są zgodne z generycznymi hierarchiami wyjątków w transakcjach i DAO. 3.4.2.3 Szablon Model-Widok-Kontroler Spring zapewnia elastyczny trój powłokowy szablon Model-Widok-Kontroler (ang. Model-View-Controller, MVC), zbudowany na bazowej funkcjonalności Springa. Programiści otrzymują wysoki stopień kontroli nad szablonem poprzez interfejsy strategii (strategy interfaces). Obsługuje on wiele technologii, w tym strony JSP, FreeMarket, Velocity, itext, Apache POI. Środkową powłokę można łatwo połączyć z powłoką innego szablonu MVC, w tym Apache Struts, WebWork albo Tapestry. Problem z wzorcem projektowym MVC polega na stworzeniu przejrzystego szablonu dla stworzenia części Modelu (np. Apache Struts). Możliwość współpracy Springa z takimi wzorcami oznacza, że programiści mogą szybko zrefaktorować (ang. refactoring) nieudaną implementację i używać sparingowej warstwy abstrakcji JDBC.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 15 3.5 Serwer Apache Tomcat Apache Tomcat to kontener aplikacji webowych (ang. web container) rozwijany w ramach projektu Apache. Jako kontener aplikacji jest serwerem, który umożliwia uruchamianie aplikacji internetowych w technologiach Java servlets i JavaServer Pages (JSP). Jest to jeden z bardziej popularnych kontenerów Web. Tomcat jest wykorzystywany w takich serwerach aplikacji J2EE jak JBoss lub Apache Geronimo. Jest również bardzo popularnym kontenerem dla samodzielnych aplikacji (nie wymagających pełnego serwera aplikacji) pisanych w środowisku Spring Framework. Apache Tomcat początkowo rozwijany był jako podprojekt projektu Apache Jakarta. W 2005 roku projekt uzyskał status samodzielnego projektu w ramach struktury projektów Apache.
16 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 4 Struktura programu 4.1 Aplikacje webowe wykonane w technologii Java Servlet Aplikacje internetowe wykonane w technologii Java Servlet opierają się na architekturze klient-serwer i są przystosowane do wykorzystywania standardowego protokołu HTTP. Klientem staje się przeglądarka stron internetowych a serwerem - aplikacja w Javie. Aplikacja taka działa jak dynamiczna witryna WWW, której zawartość zmienia się wraz ze zmianą żądań nadchodzących od klienta. HTTP czyli Hypertext Transfer Protocol jest protokołem sieci WWW, za pomocą którego klient wysyła żądanie na serwer i otrzymuje odpowiedź w postaci na przykład strony HTML. Jest to protokół bezstanowy, co oznacza, że kolejne żądania tego samego klienta nie są ze sobą w żaden sposób powiązane. Mechanizmem umożliwiającym łączenie żądań pochodzących od tego samego klienta są sesje. Sesja to pewien obszar pamięci na serwerze, który aplikacja rozpoznaje jako zbiór informacji skojarzonych z tym samym użytkownikiem. Dzieje się tak dlatego, iż klient wysyłając żądanie na serwer zawsze zawiera w żądaniu pewne parametry identyfikujące sesje. Oprócz dołączenia parametrów może dołączyć do żądania pewne dodatkowe parametry w postaci łańcuchów znaków umieszczone w treści metod GET lub POST. Parametry te są dołączane albo na końcu adresu URL poprzez metodę GET lub w nagłówku żądania dzięki metodzie POST. Serwer otrzymując żądanie sprawdza czy zawiera ono tzw. identyfikator sesji, czyli unikatowy numer dla każdej sesji. Jeśli taki numer nie istnieje serwer interpretuje żądanie jako pochodzące z nowej sesji, którą w tym momencie tworzy i generuje dla niej identyfikator. Następnie identyfikator sesji jest zawarty w odpowiedzi przekazanej do klienta. Przeglądarka zapisuje identyfikator sesji w pliku cookie jeżeli jest włączona w niej obsługa tych plików lub przepisuje go do adresu URL i tam go przechowuje. Przy następnym żądaniu pochodzącym od tego samego klienta, serwer odnajduje w nim identyfikator sesji i wie, że to żądanie pochodzi od tego samego klienta i może połączyć go z istniejącą sesją. W aplikacjach opartych o technologię Java Servlet w sesji można przechowywać nie tylko łańcuchy znaków
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 17 lecz także atrybuty w postaci obiektów. Sesje są używane przez aplikacje WWW między innymi do autoryzacji użytkownika. Protokół http używa dwóch metod do przesyłania informacji wraz z żądaniem. GET - Informacje w tej metodzie są przesyłane jako łańcuchy znaków dołączone do adresu URL czyli tzw. Query String. Wadą tej metody jest to że informacje są widoczne w treści adresu URL. W przypadku metody POST informacje zawarte są w nagłówku żądania http. W aplikacji zastosowano obydwie metody. Jeżeli aplikacja odbiera żądanie dotyczące mniejszej ilości przesłanych parametrów to użyta zostaje metoda GET. W sytuacji, gdy aplikacja obsługuje przesłanie przez formularz większej ilości danych na przykład dodanie jakiegoś obiektu do bazy danych, wówczas używana jest metoda POST. Aplikacje oparte o technologię Java posiadają w swych zasobach klasę, którą traktują jak klasę główną. Znajduje się w niej główna metoda wywoływana zawsze podczas uruchomienia aplikacji. Java wspiera tworzenie aplikacji opartych o protokół http za pomocą technologii Java Servlet będącej częścią specyfikacji J2EE. Servlet jest zwykłą klasą Javy, która dziedziczy po pewnej klasie lub implementuje pewien interfejs HttpServlet z pakietu javax.servlet. Interfejs ten wymaga od programisty zaimplementowania dwóch metod dopost() i doget(). Metody te obsługują żądania nadchodzące przez metodę POST i GET. Przykładową implementację metod dopost() i doget() przedstawia poniższy fragment programu: public class Servlet_prosty extends HttpServlet{ public void doget(httpservletrequest request,httpservletresponse response) throws ServletException{ response.setcontenttype( text/html ); PrintWriter out = response.getoutputstream(): out.prinln( <html><head></head><body> TEKST </body></html> ); } public void dopost(httpservletrequest request,httpservletresponse response) throws ServletException{ doget(request,response); } }
18 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Jak widać servlet posiada metody obsługujące każde żądanie według podanych metod http. Bardzo istotne są obiekty przekazywane w liście argumentów tych metod. Obiekt klasy HttpServletRequest reprezentuje żądanie klienta a obiekt HttpServletResponse odpowiedź serwera. Do najważniejszych metod obiektu klasy HttpServletRequest należą: getparameter( nazwaparametru ) pobiera parametry formularza, getattribute( nazwaatrybutu ) pobiera atrybut, którym może być również obiekt, setattribute( nazwaatrybutu,identyfikatorobiektu) służy ustawienia atrybutu, na odpowiedni obiekt następnie przekazany do kolejnego zasobu wraz z żądaniem, getsession() zwraca obiekt reprezentujący aktualną sesję, getdispatcherservlet() pobiera specjalny obiekt z kontekstem servletu i danej aplikacji z referencjami do wszystkich zasobów aplikacji, getremoteadress() podaje ciąg znaków zawierający adres IP komputera z którego przyszło żądanie, getcharacterencoding() pobiera kodowanie znaków żądaniu, w przesłanym setcharacterencoding() ustawia kodowanie znaków. Innym używanym bardzo często obiektem jest obiekt klasy HttpServletSession. Aby mieć do niego dostęp należy użyć metody getsession(). Następnie można już dokonywać operacji związanych z sesją. Użytecznymi metodami tej klasy są: setattribute( id_obiektu,obiekt) ustawienie obiektu w sesji, getattribute( id_obiektu ) pobranie obiektu w sesji, removeattribute( id_obiektu ) usunięcie obiektu z sesji, invalidate() unieważnienie sesji, isnew() sprawdzenie czy sesja jest nowo utworzona.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 19 Gdy do klienta zostaje wysłana odpowiedź, przez aplikację jest ona widziana jako obiekt klasy HttpServletResponse. Najważniejsze metody tej klasy to: setcontenttype() ustawia typ zawartości strony czyli, tzw. typ MIME dzięki któremu przeglądarka wie jak ma zinterpretować zawartość strony, sendredirect() wysyła przeglądarce nakaz przejścia na inny adres URL podany jako argument metody, getwriter() zwraca strumień wyjściowy do którego można zapisywać dane w postaci znakowej, getoutputstream zwraca strumień do którego zapisuje się dane w postaci binarnej. Za pomocą powyższych metod może zostać obsłużone każde żądanie trafiające do serwera.
20 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 4.2 Środowisko programistyczne Aplikację napisano wykorzystując środowisko NetBeans IDE 5.5. Jest to darmowe środowisko, które można pobrać ze strony http://www.netbeans.org. Na rysunku przedstawiony jest wygląd środowiska NetBeans. Po lewej stronie ekranu znajduje się zakładka Projects, w której zawarta jest lista wszystkich projektów otwartych w programie. Po prawej stronie ekranu znajduje się wbudowany edytor kodu, który jest konfigurowalny w bardzo szerokim zakresie. Środowisko posiada także wbudowaną wersję serwera Apache Tomcat 5.5.17. W związku z tym nie jest konieczne posiadanie osobnego serwera Tomcat niezbędnego do uruchomienia aplikacji napisanych w technologii Java Servlet. Warto jednak pamiętać,że NetBeans domyślnie uruchamia Tomcata na porcie 8084.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 21 4.3 Szkielet aplikacji Aplikacja używa wspomnianego w jednym z wcześniejszych rozdziałów szkieletu Spring Framework, który implementuje wzorce projektowe takie jak: wzorzec Model-View-Controller, wzorzec Front Controller, wzorzec Application Controller, wzorzec Command, wzorzec Dao, Application Context, wzorzec Inversion of Control (IoC), abstrakcyjnej fabryki obiektów. Pierwszym, wartym omówienia wzorcem jest Inversion of Control (IoC), czyli wzorzec odwrócenia sterowania polegający na przeniesieniu sterowania nad pewnymi obiektami do innych zewnętrznych obiektów. W technologii Spring użyta jest pewna forma tej koncepcji tworzenia aplikacji o nazwie wstrzykiwanie zależności.. Podstawową cechą takiego modelu programowania jest przeniesienie odpowiedzialności za tworzenie zależności pomiędzy obiektami na pewne zewnętrzne obiekty nazywane kontenerami. Zależności pomiędzy obiektami nie są zdefiniowane w bezpośredni sposób w kodzie aplikacji lecz ich odpowiednie ustawienie spada tzw. fabryki obiektów. Dzieje się to za pomocą pewnych metod nazywanych w programowaniu obiektowym setterami (z ang. set ustawić). W aplikacji napisanej za pomocą Spring Framework, należy wyodrębnić trzy oddzielne warstwy : warstwę prezentacji na którą składa się zespół widoków wykonanych w technologii JSP, JSTL, Spring Tags, JavaScript oraz HTML i CSS. warstwę usług, która jest całkowicie wykonana za pomocą technologii Java Servlet
22 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT warstwę DAO czyli Data Access Object warstwa ta odpowiada za interakcję z bazą danych.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 23 4.4 Warstwa prezentacji Jednym z najważniejszych wymagań stawianych dobrze zaprojektowanemu frameworkowi jest zapewnienie,by infrastruktura kontrolerów nie narzucała stosowanej technologii generacji widoków. W Springu wymóg ten jest realizowany przez zastosowanie logicznych nazw widoków oraz komponentów nazywanych resolverami widoków. Resolvery mają za zadanie przekształcać logiczne nazwy widoków na zasoby zdolne do wygenerowania samego widoku. W naszej aplikacji w warstwie prezentacji zostanie wykorzystana technologia JSP, stanowiąca jeden z elementów specyfikacji J2EE. Aby stworzyć widok używając technologii JSP, w pierwszej kolejności należy zdefiniować w kontekście aplikacji komponent resolvera widoku. <bean id="viewresolver" class="org.springframework.web.servlet.view.internalresourceviewresolver"> <property name="prefix" value="/web-inf/jsp/"/> <property name="suffix" value=".jsp"/> </bean> Po zdefiniowaniu resolvera widoku, który będzie przekształcał logiczne nazwy widoków na konkretne pliki JSP wystarczy stworzyć stronę z rozszerzeniem jsp.
24 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 4.5 Warstwa DAO Warstwa DAO to pewien zbiór metod służących do pobierania, edytowania i zapisywania informacji w jakimś określonym źródle danych. Takim źródłem może być plik XML, baza danych lub jakiś inny plik. DAO to skrót od wyrazu Data Access Object pochodzącego z języka angielskiego i oznaczającego nic innego jak zbiór obiektów odpowiedzialnych za dostęp do danych. Zastosowanie w aplikacji warstwy DAO wymaga zaimplementowania w niej dodatkowych interfejsów. Dzięki zastosowaniu tego wzorca projektowego aplikacja nie musi znać miejsca składowania danych ani też sposobu dostępu do nich. Dzięki takiemu rozwiązaniu aplikacja może zostać rozbudowana w bardzo prosty sposób. Nie ingerując w kod warstwy pośredniej możemy zmieniając DAO zmienić sposób dostępu do bazy danych. W prezentowanej aplikacji jako metoda dostępu do bazy danych została użyta warstwa pośrednia Spring Frameworka bazująca na sterowniku JDBC. Warstwa DAO wykorzystuje jeszcze jeden wzorzec projektowy a mianowicie abstrakcyjną fabrykę obiektów. Polega to na tym, że pewne obiekty są zbudowane w postaci interfejsu a nie konkretnej implementacji. Obiekty wchodzące w interakcje z tymi obiektami postrzegają je właśnie jako zbiór metod bez konkretnej implementacji. Następnie do każdego z interfejsów stworzony jest obiekt z konkretną implementacją. Dzięki takiemu rozwiązaniu obiekty końcowe można później podmienić na inne zmieniając przez to sposób dostępu do danych. Oto fragment przykładowego Dao obiektu typu KolokwiumDao będącego interfejsem: Public interface KolokwiumDao{ public Komputer getkomputer(int id_kompa); public int addpytanie(pytanie pytanie); public int setstatuspytania(statuspyt statuspyt,int id_pytania); public int deletepytanie(int id_pytania); public List getpytaniaingrupa(int id_grupy); public List getodpowiedziinpytanie(int id_pytania); public int addskalaocen(skalaocen skalaocen) public List getstudencinakolbyidgrupy(int id_grupy)... }
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 25 Jak widać jest to zbiór pewnych metod czyli inaczej mówiąc usług, których wykonania może zażądać od obiektu jakiś inny obiekt. Przykładem właśnie takiego żądania może być pobranie wszystkich pytań dla danej grupy. Służy do tego metoda, public List getpytaniaingrupa(int id_grupy); która jako argument pobiera id grupy na kolokwium a zwraca listę obiektów określonego typu. Metoda ta nie posiada konkretnej implementacji w obiekcie w którym się znajduje. Wiele aplikacji opartych o technologie J2EE używa mechanizmów dostępu do różnych zasobów danych. Jak wiadomo mechanizmami takimi mogą być sterowniki JDBC, JDO narzędzia do odwzorowania obiektowo relacyjnego typu Hibernate lub ibatis. Interfejs tych narzędzi może się znacznie różnić od siebie. Dzięki jednak zastosowaniu abstrakcyjnej fabryki DAO można używać tych narzędzii w tej samej aplikacji nie zmieniając jej kodu znacznie a jedynie zmieniając kod należący do warstwy Dao. W przypadku naszej aplikacji implementacja KolokwiumDao znajduje się w klasie KolokowiumJdbcDao, która dziedziczy po klasie JdbcDaoSupport. Klasa ta należy do pakietu Spring Framework i stanowi szablon dla obiektu oferującego funkcjonalność DAO w Springu przy użyciu sterownika JDBC. Jednym z pól tej klasy jest pole implementujące interfejs DataSource. Interfejs jest standardem w aplikacjach opartych o technologię J2EE.. W tym przypadku jako obiekt reprezentujący ten interfejs użyto standardowej postgresowej puli połączeń czyli obiektu klasy org.postgresql.jdbc2.optional.poolingdatasource. Poniżej przedstawiony jest format tego obiektu: <bean id="datasource" class="org.postgresql.jdbc2.optional.poolingdatasource"> <property name="servername" value="${jdbc.servername}"/> <property name="databasename" value="${jdbc.databasename}"/> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="datasourcename" value="a data Source" /> <property name="maxconnections" value="90"/> </bean>
26 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Pula połączeń to pewien obiekt zawierający zbiór zainicjalizowanych i otwartych połączeń. Z otwarciem nowego lub z zamknięciem starego połączenia wiążę się pewien określony koszt, który wynika z tego, że aplikacja zużywa wówczas zasoby systemowe. Poza tym użytkownik musi czekać aż operacja nawiązania połączenia się dokona. System tak zbudowany traci na wydajności, skalowalności, może znaleźć się w stanie niepotrzebnego przestoju wynikającego z wyczerpania ilości połączeń. Zamiast tego pula połączeń umieszczona w globalnym zasięgu aplikacji w postaci jednego egzemplarza korzystając z gotowych interfejsów do pobierania i zwracania połączenia obsługuje operacje wszystkich wątków aplikacji z bazą danych. Warto nadmienić iż parametry konfiguracyjne puli połączeń zostały umieszczone w osobnym pliku jdbc.properties z którego są wczytywane. Zmieniając więc te parametry zmienia się wyłącznie zawartość tego pliku nie ingerując ani w kod aplikacji ani w treść pliku definiującego jej kontekst. Warstwa Dao oparta jest więc o pewne standardowe klasy z pakietu Spring Framework. Dzięki zastąpieniu standardowego API Jdbc przez warstwę pośrednią Spring Framework unikamy podczas pisania aplikacji problemu związanego z kłopotliwym zarządzaniem obiektami klasy Connection, Statement a także obsługi wyjątków w blokach try catch. Oto fragment warstwy Dao a dokładniej konkretnej implementacji interfejsu KolokwiumDao w postaci KolokwiumJdbcDao: public class KolokwiumJdbcDao implements KolokwiumDao extends JdbcDaoSupport { public List getallsale() { return getjdbctemplate().query("select * FROM sale",new RowMapper(){ public Object maprow(resultset rs, int i) throws SQLException { Sala sala=new Sala(); sala.setid(rs.getint("id_sali")); sala.setnazwasali(rs.getstring("nazwa_sali")); sala.setkomputers(getcomputersinsala(sala.getid())); return sala; } }); }... }
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 27 Powyższa metoda pobiera z bazy danych wszystkie obiekt typu Sala. Bardzo ważnym obiektem w klasie JdbcDaoSupport jest obiekt klasy JdbcTemplate. To właśnie jego zadaniem jest pobranie z puli połączeń aktualnie dostępnego połączenia oraz wywołanie odpowiednich metod umożliwiających interakcję z bazą danych.(dodawanie, usuwanie, edycja rekordów). Obiekt klasy JdbcTemplate dostarcza wielu metod odpowiedzialnych za dokonywanie tych operacji. Oto niektóre z nich oraz przykładowa implementacja tych metod w naszej aplikacji. Update (String SQL,Object[] arglist) metoda ta posiada kilka postaci. W najczęściej spotykanej wykonuje operacje związane z dodawaniem rekordów, edytowaniem ich zawartości oraz usuwaniem rekordów z bazy danych. Pierwszym argumentem metody jest zapytanie SQL a następnym lista argumentów zapytania w postaci tablicy obiektów. Argumenty z listy zostaną powiązane z brakującymi danymi w zapytaniu za pomocą mechanizmu zwanego późnym wiązaniem zmiennych. Oto przykład takiego rozwiązania: public int deletesala(int id_sali) { return getjdbctemplate().update("delete * FROM sale WHERE id_sali=?",new Object[]{new Integer(id_sali)}); } Na listingu została przedstawiona metoda usuwająca z bazy danych salę o określonym identyfikatorze.. Dzięki zastosowaniu późnego wiązania zmiennych argumenty metody, które parametryzują polecenie SQL nie muszą być dołączane do zapytania w postaci konkatenacji znaków co z kolei wymuszało by konieczność dodatkowego filtrowania lub kodowania i dekodowania parametrów. Analogicznie przedstawia się metoda edytująca dane w bazie danych. public int editsala(sala sala) { return getjdbctemplate().update("update sale SET nazwa_sali=? WHERE id_sali=?",new Object[]{sala.getNazwaSali(),new Integer(sala.getId())}); } Innymi pomocnymi metodami klasy JdbcTemplate są metody umożliwiające pobieranie danych z bazy.
28 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Metody queryforint, queryforobject, queryforlist i query służą pobieraniu danych, które następnie są umieszczane w odpowiednich obiektach zwanych TransferObjects i przenoszone do innych warstw aplikacji. Poniżej podano przykłada użyty w aplikacji TMTTesty: public List getallsale() { return getjdbctemplate().query("select * FROM sale",new RowMapper(){ public Object maprow(resultset rs, int i) throws SQLException { Sala sala=new Sala(); sala.setid(rs.getint("id_sali")); sala.setnazwasali(rs.getstring("nazwa_sali")); sala.setkomputers(getcomputersinsala(sala.getid())); return sala; } }); } Metoda pobierająca wszystkie sale z bazy wywołuje metodę query, która pobiera trzy rodzaje argumentów. Pierwszym argumentem jest String reprezentujący zapytanie SQL, kolejnym tablica obiektów które są przekazywane do zapytania. Ostatnim argumentem jest klasa anonimowa typu RowMapper. Klasa ta nie posiada implementacji gdyż jest interfejsem,a jedyną jej metodą jest maprow (ResultSet rs, int i), która to dokonuje cyklicznego mapowania(obrobienia wyników zapytania) W metodzie tej następuje pobieranie danych z obiektu ResultSet będącego wynikiem zapytania i zapisywanie ich do nowo-utworzonego obiektu sala.następnie obiekt ten jest umieszczany na odpowiedniej kolekcji danych w tym wypadku kolekcji List. Ta kolekcja jest bardzo często spotykanym zbiorem danych w języku Java. Inna metoda odpowiedzialna za pobranie z bazy danych jakichś informacji jest metoda queryforobject(),która zwraca konkretny obiekt. Aby mogła zostać wykonana taka operacja należy skorzystać wcześniej z operacji rzutowania tego zwracanego obiektu na konkretny obiekt. Rzutowanie tego rodzaju nazywa się rzutowaniem w górę.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 29 4.6 Diagram relacji w bazie danych W bazie danych, z której korzysta aplikacja istnieje ponad 30 relacji. Poniżej znajduje się rysunek przedstawiający najistotniejsze relacje. kolokwia 1 id_kolokwium nazwa_kolokwium id_grupy_zal id_sali czas_trwania czas_odbycia notatki status sposob_przyz ilosc_grup ilosc_pytan id_skali 1 sale id_sali nazwa_sali pytania_na_kol id_pytania_kol id_grupy_kol id_pytania_pyt nr_pyt_gr 1 pytania id_pytania tresc_pyt tresc_odp status_pyt kod_prof sceny_pytan id_pow id_pytania id_sceny 1 grupy_kol id_grupy_kol nr_grupy_kol id_kolokwium odpowiedzi_studenta id_odp_stud indeks id_grupy_kol id_odp_odp tresc jednostka kod punkty 1 sceny id_sceny temat_sceny czas_trwania id_celu scena Legenda: Klucz_glówny 1 Klucz obcy Rekord bez klucza 1 odpowiedzi id_odpowiedzi id_pytania id_typu wart_punkt nr_odp_pyt tresc jednostka
30 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 4.7 Przepływ sterowania w aplikacji Pierwszym elementem aplikacji na który natrafia żądanie klienta http jest Interceptor czyli pewien moduł aplikacji WWW opartej o technologię Spring MVC, który nasłuchuje większość nadchodzących żądań do danej aplikacji. Moduł ten jako pierwszy obsługuje żądanie zanim trafi ono do innych modułów. Do jego podstawowych zadań należą: sprawdzenie czy aplikacja jest w stanie w pełni obsłużyć żądania od klienta sprawdzenie poprawności sesji, autoryzacja klienta sprawdzenie czy adres IP klienta należy do puli adresów zaufanych sprawdzenie kodowania znaków przesłanych w parametrach żądania ustawienie odpowiedniego kodowania Aby taki moduł mógł spełniać swoje zadanie, musi być umieszczony w zasięgu wszystkich zasobów do których może odwołać się klient. W naszej aplikacji Interceptor nadaje odpowiednie uprawnienia sesji klienta, status użytkownika, nazwę użytkownika oraz ustawia kodowanie UTF-8 dla parametrów przesyłanych przez żądanie.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 31 4.8 Mapowanie odpowiednich adresów URL na kontrolery Poszczególne adresy URL, których może użyć klient do wywołania odpowiednich działań aplikacji, przechowywane są w specjalnym obiekcie (kontenerze) który rozpoznaje adresy URL i kieruje żądanie pod odpowiedni kontroler. Obiektem służącym do takiego mapowania adresów jest obiekt klasy SimpleUrlHandlerMapping z pakietu Spring Framework. Umieszczając w kontekście aplikacji obiekt klasy SimpleUrlHandlerMapping możemy skonfigurować go w odpowiedni sposób tzn. ustawić mapowanie adresów URL na odpowiednie kontrolery, które obsłużą żądania klienta. Konfiguracja obiektu mapującego w przypadku naszej aplikacji znajduje się w pliku dispatherservlet.xml. Poniżej przedstawiono fragment tego pliku: <bean id="urlmapping" class="org.springframework.web.servlet.handler.simpleurlhandlermapping"> <property name="interceptors"> <list> <ref bean="userandcodinginterceptor"/> </list> </property> <property name="mappings"> <props> <prop key="welcome.htm">inputcontroller</prop> <prop key="installsql.htm">inputcontroller</prop> </props> </property> </bean> Fragment pliku dispather-servlet.xml z listingu przedstawia część konfiguracji obiektu mapującego adresy URL na odpowiednie kontrolery. Konfiguracja taka musi zawierać standardowy znacznik <bean> w którym jako atrybut podana jest nazwa nowopowstałego obiektu id="urlmapping" oraz nazwa klasy wraz z pełną ścieżką dostępu do niej w hierarchii bibliotek. Następnie poprzez znaczniki <property> ustawiane są w odpowiedniej kolejności pola obiektu. W naszej aplikacji są to dwa pola właściwości:
32 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Interceptors w którym jest zdefiniowana lista interceptorów Mappings w którym jest zdefiniowana lista odwzorowań URL (klucz) kontroler (wartość)
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 33 4.9 Dispacher-servlet W aplikacjach sieciowych opartych na technologii JAVA-SERVLET używany jest wzorzec projektowy o nazwie Front-Controller. Ma on za zadanie odbierać wszystkie żądania klienta i decydować gdzie je kierować. W poprzednim punkcie zostało wspomniane o obiekcie odwzorowującym adresy URL na odpowiednie kontrolery obsługujące dane żądanie. W technologii Spring Framework jako obiekt front-controller używany jest servlet nazywany dispatcher-servlet. Servlet taki musi dziedziczyć po klasie należącej do pakietu Spring MVC o nazwie DispatcherServlet. Klasa, której instancje pełnią funkcję front-controllera w aplikacji, musi spełniać kilka założeń: musi opierać się o mechanizm Java Beans, musi posiadać mechanizm, który pozwoli jej sterować żądaniami klienta, musi mieć zaimplementowany pewien mechanizm umożliwiający zwrócenie odpowiedniego widoku, powinna posiadać łatwo konfigurowalny kontekst, a także mieć dostęp do głównego kontekstu aplikacji. Przedstawione powyżej wymagania spełnia klasa DispatcherServlet. Na poniższym rysunku pochodzącym z dokumentacji technologii Spring MVC przedstawiono schemat przejścia żądania w aplikacji Spring MVC.
34 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Incoming request Front controller Delegate request model Handle request Controller Return response Return control model Render response Delegate rendering of response Create model View template Servlet engine (e.g. Tomcat) Jak widać na rysunku żądanie najpierw trafia do Front-Controllera, tam obiekt ten podejmuje decyzję, w jaki sposób obsłużyć żądanie. Przekazuje obsługę żądania tzn. deleguje obsługę do odpowiedniego kontrolera.. Ten z kolei wykonuje odpowiednie operacje i zwraca do Front-Controllera odpowiedni model czyli dane, oraz nazwę widoku, który musi być zwrócony klientowi. w postaci strony JSP. Front-Controller przekazuje sterowanie wraz z potrzebnymi danymi do odpowiedniego widoku(używa do tego obiektu o nazwie viewresolver). Servlet pełniący funkcję Front-Controllera musi być uprzednio skonfigurowany w pliku Web.xml. <servlet> <description>dispatcher servlet for this application</description> <servlet-name>dispatcher</servlet-name> <servlet-class> org.springframework.web.servlet.dispatcherservlet </servlet-class>
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 35 </servlet> <load-on-startup>2</load-on-startup> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> W momencie gdy serwer Tomcat uruchamia aplikacje, natrafia na powyższy fragment pliku Web.xml i tworzy instancję servletu o identyfikatorze dispatcher, będącego instancją klasy DispatcherServlet. Następnie ustawia kierowanie wszystkich adresów URL o prefiksie.htm na ten servlet. <?xml version="1.0" encoding="utf-8"?> <beans> <bean id="professorregistervalidator" class="validators.professorregistervalidator"> <property name="professordao" ref="professordao"/> </bean> <bean id="writecolokwiumcontroller" class="controllers.writecolokwiumcontroller"> <property name="uprawnienia" ref="uprawnienia"/> <property name="kolokwiumdao" ref="kolokwiumdao" /> <property name="studentdao" ref="studentdao"/> <property name="methodnameresolver" ref="writecolokwiumcontrollerresolver"/> </bean> <bean id="addscenaform" class="controllers.addscenaform"> <property name="ngpdao" ref="ngpdao" /> <property name="uprawnienia" ref="uprawnienia"/> <property name="formview" value="addscena"/> <property name="successview" value="ngpcele"/> </bean> </beans> Na listingu został przedstawiony fragment pliku dispatcher-servlet.xml. Pierwsza linia to deklaracja użytej wersji języka XML oraz zastosowanego kodowania znaków. Następna linia to znacznik <beans> otwierający ciało pliku. Dalej przedstawiona jest konfiguracja obiektu odpowiedzialnego za walidację danych w przypadku rejestracji nowego wykładowcy, a także konfiguracja obiektów
36 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT writecolokwiumcontroller (pisanie kolokwium przez studenta) oraz addscenaform (formularz dodawania nowych scen do instrukcji ).
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 37 4.10 Kontrolery oraz wzorce projektowe command oraz Applicationcontroller. Kolejnym ważnym wzorcem projektowym stosowanym w architekturze aplikacji opartych o technologię J2EE jest wzorzec application-controller. Jest on ściśle powiązany z wzorcem projektowym command. Służą one obsługiwaniu żądań klienta w warstwie usług. Zgodnie z tym co zostało napisane w poprzednich rozdziałach żądania nadchodzące od klienta HTTP trafiają najpierw na obiekt dispatcher-servlet.xml będący punktem wejściowym aplikacji. Następnie wysyłane jest zapytanie do interceptora, czy żądanie może zostać obsłużone. Jeśli interceptor nie odrzuci żądania dispatcher kieruje żądanie do odpowiedniego kontrolera. Poprzez pojęcie kontrolera rozumiany jest właśnie application-controler. W omawianej aplikacji istnieje kilkanaście kontrolerów odpowiedzialnych za różne akcje. public ModelAndView przegpytanie(httpservletrequest request,httpservletresponse response) throws PropertyVetoException{ if(!checkprivilleges(request,"bazastudentow")) return new ModelAndView("nonPrivilleges"); int id_pytania=integer.parseint(request.getparameter("id_pytania")); Pytanie pytanie=kolokwiumdao.getpytanie(id_pytania); List odpowiedzi=kolokwiumdao.getodpowiedziinpytanie(id_pytania); ModelAndView mav=new ModelAndView("przegPytanie"); mav.addobject("odpowiedzi",odpowiedzi); mav.addobject("pytanie",pytanie); mav.addobject("typyodp",kolokwiumdao.gettypyodp()); return mav; } Na listingu została przedstawiona metoda umożliwiająca przeglądanie szczegółowych informacji na temat określonego pytania na kolokwium. Metoda ta znajduje się w klasie BazaKolokwiumController z pakietu controllers. Przyjmuje ona dwa argumenty - obiekty będące żądaniem klienta i skierowaną do niego
38 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT odpowiedzią. Metoda zwraca obiekt ModelAndView, zawierający w sobie logiczną nazwę generowanego widoku, ModelAndView mav=new ModelAndView("przegPytanie"); i model czyli dane wyświetlane na tej stronie, przekazywane do tego widoku w postaci obiektów. mav.addobject("odpowiedzi",odpowiedzi); mav.addobject("pytanie",pytanie);
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 39 4.11 Obsługa żądań W celu lepszego zrozumienia sposobu obsługi żądań w naszej aplikacji, zostaną teraz przedstawione fragmenty kodu, służące do obsługi wyświetlenia listy wszystkich kolokwiów dostępnych w aplikacji. Pierwszym zdarzeniem, które musi nastąpić aby możliwe było wyświetlenie listy kolokwiów jest zgłoszenie takiego właśnie żądania przez klienta. W pasku adresu przeglądarki musi pojawić się adres : http://127.0.0.1/tmttesty/bazakolokwiow.htm Zgodnie z tym co zostało napisane w poprzednich rozdziałach, żądanie takie trafia do front-controllera czyli pliku dispatcher-servlet.xml. Następnie zostaje przechwycone przez interceptor, który sprawdza czy żądanie może zostać obsłużone i jeśli interceptor potwierdzi możliwość wykonania żądania wraca ono do frontcontrollera. Kolejnym krokiem jest określenie kontrolera który będzie w stanie obsłużyć żądanie. Proces ten składa się z 3 kroków. W pierwszym, następuje mapowanie adresu url na odpowiedni kontroler. <bean id="urlmapping" class="org.springframework.web.servlet.handler.simpleurlhandlermapping"> <property name="interceptors"> </property> <property name="mappings"> <props> <prop key="bazakolokwiow.htm">bazakolokwiowcontroller</prop> </props> </property> </bean> W drugim kroku żądanie pozostając w pliku dispatcher-servlet.xml trafia do Bean a o identyfikatorze bazakolokwiowcontroller. <bean id="bazakolokwiowcontroller" class="controllers.bazakolokwiumcontroller">
40 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT <property name="uprawnienia" ref="uprawnienia"/> <property name="kolokwiumdao" ref="kolokwiumdao" /> <property name="ngpdao" ref="ngpdao" /> <property name="studentdao" ref="studentdao"/> <property name="methodnameresolver" ref="bazakolokwiowcontrollerresolver"/> </bean> W beanie z listingu odbywa się konfiguracja kontrolera. Odwołanie do klasy z uprawnieniami a także do wszystkich obiektów DAO wykorzystywanych w obrębie kontrolera. Bardzo istotnym polem tego beana jest <property name="methodnameresolver" ref="bazakolokwiowcontrollerresolver"/> Dzięki niemu żądania mogą być obsługiwane przez zdefiniowane w kontrolerze (krok 3). odpowiednie metody <bean id="bazakolokwiowcontrollerresolver" class="org.springframework.web.servlet.mvc.multiaction.propertiesmethodname Resolver"> <property name="mappings"> <props> <prop key="/bazakolokwiow.htm">bazakolokwiow</prop>... </props> </property> </bean> Po tym kroku następuje przejście z front-controlera do bazakolokwiowcontroller, oraz zgodnie z konfiguracją beana methodnameresolver, wywołanie metody bazakolokwiow. public ModelAndView bazakolokwiow(httpservletrequest request,httpservletresponse response) throws PropertyVetoException{ if(!checkprivilleges(request,"bazastudentow")) return new ModelAndView("nonPrivilleges"); return new ModelAndView("bazaKolokwiow","kolokwia",kolokwiumDao.getAllKolokwia()); }
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 41 Metoda ta przyjmuje dwa argumenty (żądanie klienta, odpowiedź serwera). W ciele metody znajduje się instrukcja sprawdzająca czy użytkownik posiada uprawnienia do przeglądania tego zasobu i jeśli posiada takie uprawnienia zostaje zwrócony widok o nazwie logicznej bazakolokwiow i zawartości wygenerowanej za pomocą metody getallkolokwia() z kontrolera kolokwiumdao. public interface KolokwiumDao {... public List getallkolokwia();... } W kolokwiumdao znajduje się lista metod których właściwa implementacja dla przypadku naszej aplikacji znajduje się w kontrolerze kolokwiumjdbcdao. public List getallkolokwia() { return getjdbctemplate().query("select * FROM kolokwia,grupy_zajeciowe,skale_ocen,statusy_kolokwium,roki,sale WHERE (kolokwia.id_grupy_zaj=grupy_zajeciowe.id_grupy and kolokwia.status=statusy_kolokwium.status_kol and kolokwia.id_skali=skale_ocen.id_skali and grupy_zajeciowe.id_roku=roki.id_roku and kolokwia.id_sali=sale.id_sali)",new RowMapper(){ public Object maprow(resultset rs, int i) throws SQLException { Kolokwium kolokwium=new Kolokwium(); kolokwium.setid(rs.getint("id_kolokwium")); kolokwium.setnazwakolokwium(rs.getstring("nazwa_kolokwium"));... kolokwium.setgroupactivity(groupactivity); return kolokwium; } } }); Metoda przedstawiona na listingu, pobiera z bazy danych wszystkie informacje na temat kolokwiów, i przygotowuje wyniki do wyświetlenia w widoku bazakolokwiow. Następnie korzystając z tej nazwy logicznej dispatcher-servlet odwołuje się do pliku bazakolokwiow.jsp, który zajmuje się wyświetleniem na ekranie, otrzymanych z bazy danych informacji o kolokwiach. Przedstawiona w tym
42 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT punkcie organizacja obsługi żądania może wydawać się skomplikowana, jest to jednak system, który można bardzo łatwo rozwijać i modyfikować, nie zmieniając kodu wcześniej zaimplementowanych elementów.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 43 4.12 Nowe typy odpowiedzi Aplikacja posiada również pewną przydatną z punktu widzenia zarówno administratora serwisu jak i prowadzącego zajęcia. Mianowicie w przypadku dodania nowego pytania, gdy w istniejącej puli opcji do wyboru zabraknie określonego typu odpowiedzi użytkownik jest w stanie sam zdefiniować nowy typ odpowiedzi. Żeby to zrobić musi wykonać kilka czynności prowadzących w efekcie końcowym do wygenerowania nowego typu odpowiedzi. Należy zacząć od lekkiej modyfikacji bazy danych, przykładowo chcemy dodać nowy typ odpowiedzi, który będzie przyjmował zbiór punktów w postaci (a,b); (c,d) itd. Możemy osiągnąć następującą instrukcją SQL: insert into typy_odp (id_typu,opis_typu_odp) VALUES (10, 'zbior punktów postaci (a,b); (c,d);... '); delete from typy_odp where id=6; ALTER TABLE sceny ADD COLUMN status INT8; ALTER TABLE sceny ADD COLUMN status_pyt INT8; UPDATE sceny SET status=0; Następnie w instrukcji warunkowej switch, w obiekcie kolokwiumcontroler.java należy zaimplementować kolejny numer instrukcji case wraz z opisem tekstowym jak w przykładzie poniżej: case 10: form.append("odpowiedź proszę podać w formie (a,b);(c,d);(e,f);... ;(x,z) <br><br><br> <input type=\"text\" name=\""+par+"\" value=\""+tresc+"\" />"); break; w metodzie form.append() trzeba wpisać to co ma zostać wyświetlone na ekranie studenta podczas pisania kolokwium. Kolejnym koniecznym krokiem do wykonania jest dodanie w obiekcie Odpowiedz.java w metodzie setwysw() następującą instrukcje: case N: // gdzie N jest kolejną cyfrą this.wysw=this.tresc; break;
44 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT która umożliwia wyświetlenie pożądanej odpowiedzi. Analogicznie postępujemy z plikiem OdpowiedzStudenta.java, gdzie należy dokonać identycznej modyfikacji kodowej w metodzie o identycznej nazwie. W obiekcie PoprawOdpowiedz.java w metodzie popraw() dodajemy następującą instrukcje: case N: // gdzie N jest kolejną cyfrą end=this.poprawtyp(this.odpowiedzstudenta.gettresc(),this.odpowiedzstudenta.getodpowiedz().gettresc()); break; gdzie poprawtyp() to nazwa metody sprawdzającej poprawności odpowiedzi studenta, która zwraca 1 w przypadku odpowiedzi poprawnej bądź 0 w przypadku odpowiedzi błędnej. Ostatnim krokiem jest dodanie instrukcji case z odpowiednio następnym numerem instrukcji case w metodzie zapiszodpowiedzi() jak w przykładzie poniżej: case 10: tresc=request.getparameter("pyt"+pytanie.getnrpytgrup()+"odp"+odpowiedz.get Nr_pyt_gr()).trim(); odpowiedzstudenta.setgrupakol(grupakol); odpowiedzstudenta.setindex(index); odpowiedzstudenta.setkod(kod); odpowiedzstudenta.setkolokwium(grupakol.getkolokwium()); odpowiedzstudenta.setodpowiedz(odpowiedz); odpowiedzstudenta.settresc(tresc); odpowiedzstudenta.setjednostka(""); poprawodpowiedz=new PoprawOdpowiedz(); poprawodpowiedz.setodpowiedzstudenta(odpowiedzstudenta); pun=poprawodpowiedz.popraw(); odpowiedzstudenta.setpunkty(pun); sumapunkt=sumapunkt+pun; kolokwiumdao.upadteodpowiedzstudenta(odpowiedzstudenta); break; powyższą modyfikację należy zaimplementować w obiekcie WriteColokwiumController.java.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 45 5 Funkcjonalny opis aplikacji Po uruchomieniu aplikacji TMTTesty, użytkownik zostanie powitany ekranem logowania. Jeśli użytkownik nie posiada jeszcze swojego loginu i hasła, może się zarejestrować. Po zalogowaniu użytkownik zostanie przekierowany na stronę główną.
46 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Nawigacja w aplikacji została zorganizowana dwupoziomowo. Główne menu zostało na rysunku oznaczone czerwonym, a menu pomocnicze zielonym obramowaniem. Opcje wyświetlane w menu pomocniczym zależą od opcji wybranej w menu głównym.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 47 5.1 Zakładka kolokwia Z poziomu zakładki Kolokwia, użytkownik ma możliwość: Wyświetlenia listy wszystkich kolokwiów Wyświetlenia listy skali ocen Dodania nowego kolokwium 5.1.1 Wyświetlanie listy wszystkich kolokwiów Na rysunku została przedstawiona lista prezentująca informacje na temat wszystkich kolokwiów dostępnych w bazie danych. Poszczególne kolokwia różnią się statusami (dla łatwiejszego rozróżnienia pole statusu wypełniane jest różnymi kolorami). Użytkownik może przeglądać a także dodawać lub usuwać pytania które mają zostać użyte w kolokwium. W trakcie przeprowadzania kolokwium, prowadzący zajęcia może otworzyć Panel Kolokwium w którym widnieją informacje na jego temat, łącznie z informacjami o studentach którzy piszą kolokwium. System wyświetla odpowiedzi studentów, a także umożliwia indywidualne zakończenie kolokwium wybranego studenta, na przykład w momencie przyłapania go na korzystaniu z niedozwolonych pomocy. Po zakończeniu kolokwium, z panelu możliwe jest wygenerowanie Raportu, który bardzo łatwo przenieść do arkusza kalkulacyjnego jak MS Excel.
48 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 5.1.2 Skala ocen Na rysunku została przedstawiona lista skal ocen z wartościami w procentach określającymi ocenę studenta z kolokwium na podstawie uzyskanych punktów. Przykładowo : Jeśli suma punktów na kolokwium wynosi 100 a student uzyskał 73 punkty to według skali przedstawionej na rysunku uzyska ocenę 4.0. Istniejącą skalę użytkownik może edytować poprzez kliknięcie na symbol ołówka, a w razie potrzeby ma możliwość stworzenia nowej skali ocen. 5.1.3 Dodawanie nowych wzorów Istnieje także możliwość dodania nowych wzorów, które później znajdują zastosowanie przy dodawaniu ich do nowo tworzony lub też edytowanych pytań. Aby tego dokonać należy skopiować nowe wzory w postaci plików.jpg,.jpeg,.jpg lub.png do następującej lokacji na dysku twardym: C:/GS_TMT_module/apache-tomcat-5.5.20/webapps/TMTTesty/themes/wzory 5.1.4 Utworzenie nowego kolokwium Proces tworzenia nowego kolokwium składa się z 2 etapów. Pierwszym jest utworzenie nowego pustego kolokwium,dla którego określamy nazwę, czas trwania, liczbę grup,liczbę pytań dla grup. Wybieramy wcześniej zdefiniowaną skalę ocen oraz salę, w której będzie się odbywało kolokwium.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 49 Po wypełnieniu niezbędnych pól formularza z rysunku oraz kliknięciu przycisku Dodaj, kolokwium otrzymuje status Brak wszystkich pytań oznaczony na liście kolokwiów kolorem błękitnym. Drugim etapem tworzenia kolokwium jest przyznanie pytań dla poszczególnych grup. W tym celu użytkownik musi kliknąć w przycisk Przeglądaj na liście kolokwiów.
50 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Po kliknięciu tego przycisku użytkownik otrzymuje szczegółowe informacje o kolokwium wraz z listą grup. Klikając przycisk Przeglądnij grupę, użytkownik będzie w stanie dodać dla grupy,wcześniej utworzone pytania. Po dodaniu wszystkich pytań kolokwium uzyska status Gotowe do przeprowadzenia. Przyjrzyjmy się nieco dokładniej jak krok po kroku możemy stworzyć kolokwium za pomocą omawianego systemu. Po utworzeniu nowego kolokwium oraz ustaleniu wszystkich potrzebnych do tego celu danych możemy przystąpić do dodania pytań do danego kolokwium. Koniecznie należy pamiętać o tym, że nie możemy zarówno edytować jak i usunąć pytania które już jest powiązane z kolokwium przeprowadzanym bądź oczekującym na przeprowadzenie. Można to zaobserwować poprzez pojawienie się komunikatu w miejscu gdzie normalnie jest opcja usunięcia pytania oraz znika ikona ołówka, która zawiera przekserowanie do opcji edycji pytania.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 51 Po dodaniu pytań oraz upewnieniu się, że wszystkie podane wcześniej dane są poprawne aplikacja jest gotowa do przeprowadzenia kolokwium, co sygnalizuje przez podświetlenie pola na zielona oraz stosowny komunikat.
52 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Wówczas po naciśnięciu przycisku Start kolokwium i odpowiedzeniu twierdząco na pytanie czy na pewno chcemy to zrobić, aplikacja startuje kolokwium. Studentów zalogowanych na dane kolokwium widzimy poniżej informacji o kolokwium. Wykładowca ma przez cały czas trwania kolokwium opcje jego zakończenia. Wykładowca posiada również opcje podglądu postępów na bieżąco każdego studenta z osobna, jeśli tylko student korzysta z opcji Zapisz odpowiedzi. Wykładowca jest w stanie także zakończyć kolokwium indywidualnego studenta podczas przeglądania profilu jego kolokwia.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 53 Istnieje opcja dodania własnych uwag oraz notatek bieżących na temat konkretnego studenta, które to są cyklicznie zapisywane w profilu kolokwium studenta indywidualnego.
54 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Po pomyślnym zakończeniu kolokwium prowadzący posiada opcje podglądu kilku newralgicznych dla niego informacji o każdym konkretnym studencie w zakładce kolokwiów takich jak: Nr indeksu, Grupa, Imię oraz Nazwisko studenta, Status (Pisze, zakończył etc.), Punkty, Proponowana przez aplikacje ocena, Czy jeszcze pisze.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 55 Po dokonaniu oceny wszystkich studentów uczestniczących w kolokwium prowadzący posiada opcje wygenerowania raportu z przeprowadzonego kolokwium. Istnieje również opcja wyeksportowania tegoż raportu do arkusza kalkulacyjnego np. MS Exel, można tego dokonać zaznaczając tabele wygenerowaną przez aplikacje oraz skopiowanie jej i późniejsze wklejenie do arkusza. Wykładowca jest w stanie wystawić ocenę odmienną od proponowanej przez aplikacje wybierając odpowiednia opcję z opadającego menu w polu ocena.
56 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Po zakończeniu kolokwium prowadzący ma opcje ponownego wglądu oraz ponownego utworzenia raportu w przypadku zgubienia kopii zapasowej, może także całkiem usunąć przeprowadzone kolokwium z bazy danych. Wykładowca musi posiada również opcje usunięcia pytania nawet podczas przeprowadzenia danego kolokwium jeżeli uzna je za źle sformułowane bądź zawierające jakieś błędy. Wówczas na ekranie pojawi się następujący komunikat.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 57 5.2 Zakładka Pytania Z poziomu zakładki Pytania, użytkownik ma możliwość: Wyświetlenia listy wszystkich pytań Dodania nowego pytania 5.2.1 Wyświetlanie listy pytań Na rysunku została przedstawiona lista przykładowych pytań utworzonych na potrzeby kolokwium. W celu ułatwienia nawigacji, przy każdym pytaniu są strzałki nawigacyjne (góra, dół) których kliknięcie powoduje odpowiednio rozwiniecie lub zwinięcie szczegółów na temat wybranego pytania. Istnieje również opcja bezpośredniego podglądu odpowiedzi do danego pytania klikając na ikonę żaróweczki. Klikając na ikonę ołówka zostaniemy przeniesieni do ekranu edycji danego pytania. 5.2.2 Dodanie nowego pytania Dodawanie nowych pytań składa się z kilku etapów. Najpierw użytkownik podaje treść pytania w polu tekstowym, wybiera ilość odpowiedzi dla danego pytania. Następnie wybiera typ odpowiedzi( liczba całkowita, współrzędne punktu, liczba rzeczywista z dokładnością do 4 miejsc po przecinku itp.) Ostatnim etapem jest
58 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT wpisanie poprawnej odpowiedzi i wybranie z listy rozwijanej wartości punktowej przyznawanej studentowi za poprawne rozwiązanie.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 59 5.3 Zakładka Studenci Z poziomu zakładki Studenci, użytkownik ma możliwość: Wyświetlenia listy roczników (dodanie nowego rocznika), Ustalenia rozkładu zajęć dla danej grupy zajęciowej (wraz z listą studentów tej grupy), Wyświetlenie listy zdefiniowanych sal komputerowych (wraz z listą komputerów w danej sali). 5.3.1 Wyświetlanie listy roczników Na rysunku przedstawiono listę roczników wraz z możliwością stworzenia nowego rocznika (kierunek, specjalność), edytowania oraz usuwania wcześniej utworzonych. 5.3.2 Rozkład zajęć Na rysunku przedstawiono listę grup wraz z możliwością stworzenia nowej grupy, edytowania lub usuwania wcześniej utworzonej, a także określenia listy studentów (Numer albumu, Imię, Nazwisko) w danej grupie. 5.3.3 Klonowanie sal
60 Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT Wyżej przedstawiono rysunek, który obrazuje opcje klonowanie sali. Można to zrobić w zakładce Studenci, lista sal. Możliwość ta jest bardzo pomocna w momencie przeprowadzania kolokwiów w więcej niż jednej sali o podobnym układzie stanowisk komputerowych, bądź ich liczbie. Wystarczy po sklonowaniu zmienić kilka kluczowych informacji odnośnie nowych stanowisk. Przede wszystkim należy pamiętać o zmianie adresów IP oraz nazwie stanowiska komputerowego.
Rozbudowa funkcjonalności systemu nauczająco-testującego do programu TMT 61 5.4 Zakładka Plan zajęć Z poziomu zakładki Plan zajęć, użytkownik ma możliwość: Wyświetlenia listy planów nauczania, Wyświetlenie listy celów nauczania, Przejścia do modułu Instrukcje. 5.4.1 Lista planów nauczania Na rysunku przedstawiono listę planów nauczania czyli informacje o ilości zajęć w semestrze oraz o czasie trwania pojedynczego zajęcia. Istnieje też zdefiniowania nowego planu a także Przeglądania i Generowania planu. Kliknięcie przycisku Przeglądaj spowoduje wyświetlenie szczegółowych informacji na temat wybranego Planu nauczania (rys..), wraz z możliwością edycji poszczególnych zajęć.