LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Java na web VII. - MVC I.

V dnešním díle seriálu si předvedeme architekturu MVC v praxi, vytvoříme controller a budeme pomocí něj zpracovávat příchozí GET a POST dotazy.

1.7.2013 00:00 | Petr Horáček | Články autora | přečteno 9334×

Aplikace z minulého dílu byla postavena na samotném servletu, který zpracovával dotazy přicházející z jediné URL. Rozšiřování takové aplikace by mohlo probíhat přidáváním dalších servletů, s větším rozsahem by ale přišli i problémy s přehledností, údržbou a dalším rozšiřováním. Tento problém můžeme ale snadno vyřešit jedním controllerem jakožto centrálním prvkem zajišťujícím základní logiku, servírování dat a předávání viewů.

Příprava projektu

Dejme se tedy do práce. Vytvořte nový projekt webové aplikace s názvem JNW7 (jako Java Na Web 7). V kartě Source Packages vytvořte nový balíček s názvem servlety. Do vytvořeného balíčku přidejte nový servlet Controller, v průvodci vytvořením však neodškrtávejte možnost „Add information to deployment descriptor (web.xml)“, do vstupu URL Pattern(s) pak přidejte všechny URL, které bude naše aplikace využívat, tedy: „/zapisky, /upravit, /pridat, /smazat, /ulozitupravy“. Po vygenerování servletu si všimněte anotace určující adresy jež mají být přesměrovány k servletu.>

Vygenerovaný obsah třídy servletu smažte a vložte toto:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) 
       					 throws ServletException, IOException {
    String adresa = request.getServletPath();
    if(adresa.equals("/zapisky")) {
        // TODO: kód pro výpis zápisků
    }
    else if(adresa.equals("/upravit")){
        // TODO: kód pro vygenerování stránka určené k úpravě zápisku
    }
    else {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
    }
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        					throws ServletException, IOException {
    String adresa = request.getServletPath();
    request.setCharacterEncoding("UTF-8");
    if(adresa.equals("/pridat")) {
        // TODO: kód pro zapsání nového zápisku do seznamu
    }
    else if(adresa.equals("/ulozitupravy")){
        // TODO: kód pro uložení úprav provedených na zápisku
    }
    else if(adresa.equals("/smazat")){
        // TODO: kód pro smazání zápisku ze seznamu
    }
    else {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
    }
}

Jak vidíte, nachází se zde dvě metody, první z nich zpracovává příchozí dotazy pomocí metody GET, v našem případě obstarává a) výpis stránky se seznamem zápisků na adrese /zapisky a b) výpis stránky s formulářem pro úpravu stávajících zápisků na adrese /upravit. Prohlédněme si obsah této metody. Hned na začátku uložíme požadovanou relativní URL do proměnné adresa. Následovně projdeme několik podmínek, pomocí kterých se pokusíme adresu přiřadit k určité akci, Pokud nebude k adrese žádná akce přiřazena, klientovi se odešle HTTP hláška 404 „soubor nenalezen“.

Tip: Pro zlepšení přehlednosti vyvíjeného projektu můžeme využít zvláštní komentáře začínajících slovem „TODO:“ a pokračujících textem popisujícím chybějící kód. Pokud si teď necháme zobrazit panel Action Items (Window → Action Items), objeví se před námi seznam všech těchto komentářů (umístěných v souboru, v projektu, či ve všech projektech).

Druhá metoda je té první velice podobná. Zpracovává dotazy s metodou POST pro a) přidání nového zápisku na adrese /pridat, b) uložení úprav stávajícího zápisku na adrese /ulozit upravy a c) smazání zápisku na adrese /smazat. Oproti předchozí metodě je zde navíc řádek nastavující kódování dotazu v UTF-8.

Tip: Vytvořenou kostru Controlleru si můžete pro další použití uložit jako šablonu, stačí v kartě Source Packages kliknout pravým tlačítkem na třídu Controller a zadat „Save As Template“. Nyní můžete přidat tento Controller do projektu jako kterýkoliv jiný soubor.

Tvorba nového souboru

Model

Stejně jako v minulém díle, budou i nyní základní jednotkou aplikace jednotlivé zápisky, tentokrát se ale budou skládat ze dvou textových polí – nadpisu a obsahu. Pojďme tedy vytvořit jejich model. V kartě Source Packages vytvořte nový balíček s názvem modely. Do tohoto balíčku přidejte novou třídu Javy pod názvem Zapisek a vložte do ní kód modelu:

package modely;

public class Zapisek {

    private String nadpis;
    private String obsah;

    public Zapisek(String nadpis, String obsah){
        this.nadpis = nadpis;
        this.obsah = obsah;
    }  

    public void setNadpis(String nadpis){
        this.nadpis = nadpis;
    }

    public void setObsah(String obsah){
        this.obsah = obsah;
    }

    public String getNadpis(){
        return nadpis;
    }

    public String getObsah(){
        return obsah;
    }  
}

Tato třída obsahuje dvě soukromé proměnné nadpis a obsah, ty je možné upravovat a číst pomocí metod getNadpis(), getObsah(), setNadpis() a setObsah(). Názvy těchto metod musí vždy začínat get/set, následovat po nich musí název proměnné s velkým prvním písmenem. Při tvorbě nového zápisku je nutné předat nadpis i obsah.

Tip: Pro zobrazení nápovědy příkazů stiskněte Ctrl+Mezerník, seznam se přizpůsobuje již napsanému textu a okolnímu kódu.

Controller podruhé

Vraťme se zpět ke controllerum do jeho třídy mimo metody vložíme nový seznam zápisků, který bude sloužit jako provizorní databáze:

public List<Zapisek> zapisky = new ArrayList(); 

Nyní už k funkcím na určených adresách.

/zapisky

Začněme s výpisem seznamu zápisků. Tento kód bude vypadat stejně jako v minulém díle:

if(adresa.equals("/zapisky")){
    request.setAttribute("zapisky", zapisky);
    request.getRequestDispatcher("/WEB-INF/view/zapisky.jsp").forward(request, response);
}

Na prvním řádku zapíšeme do atributu requestu seznam zápisků, na druhém pak pomocí RequestDispatcheru předáme objekty request a response viewu zapisky.jsp.

Kořenová adresa /

V minulém díle se zápisky vypisovaly na kořenové adrese aplikace, stejně bychom to chtěli i dnes, v servletu Controller je však zadání kořenového URL / poněkud problematické, proto se nachází výpis zápisků na adrese /zapisky. Nastavení domovské adresy aplikace je však jednoduché.

Ve složce WEB-INF vytvoříme nový Standard Deployment Descriptor (web.xml), možná jej bude nutné najít v nabídce other. V novém DD se přesuňme do záložky Pages a přidejme novou Welcome page (uvítací stránku) „zapisky“, adresy je sem nutné zadávat bez prvního lomítka. V XML to vypadá asi takto:

<welcome-file-list>
   <welcome-file>zapisky</welcome-file>
</welcome-file-list>

/upravit

Vraťme se zpět ke controlleru, na adrese /upravit se bude nacházet kód sloužící pro vypsání stránky s formulářem úpravy. Konkrétní zápisek identifikujeme pomocí jeho indexu, který předáme jako parametr v adrese. Nápříklad úprava zápisku č. 2 se tedy bude nacházet na adrese /upravit?index=2. Kód tedy bude vypadat nějak takto:

else if(adresa.equals("/upravit")){
    int index = Integer.parseInt(request.getParameter("index"));
    if(zapisky.get(index) != null) {  
        request.setAttribute("zapisek", zapisky.get(index));
        request.getRequestDispatcher("/WEB-INF/view/upravit.jsp").forward(request, response);    
    }
    else {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
    }
}

Nejprve zde přijmeme parametr index a poté ověříme zda se zápisek o onom indexu v seznamu nachází. Pokud vše vyjde, do requestu se zapíše vyžádaný zápisek a zobrazí se daný view. Pokud nebude zápisek existovat odešle se chybová hláška 404.

Přesměrování

Metoda POST je často využívána ke zpracování formulářů, u kterých si nepřejeme nebo není možné předávat atributy v adresním řádku. My tuto metodu v naší aplikaci užijeme pro smazání, vytvoření a úpravu zápisků. Po každé z těchto operací je třeba uživatele opět přesměrovat na původní stránku. Pro toto přesměrování na metodu GET se užívá HTTP stav 303, tedy přesměrování (více o HTTP stavech na: http://cs.wikipedia.org/wiki/Stavov%C3%A9_k%C3%B3dy_HTTP).

Abychom se nemuseli opakovat v zadávání této často užívané operace vytvoříme si vlastní funkci:

private void presmeruj(HttpServletRequest request, HttpServletResponse response, String url) {
    response.setStatus(HttpServletResponse.SC_SEE_OTHER);
    response.setHeader("Location", request.getContextPath() + url);
}

Jak vidíte, funkci je třeba předat adresu pro přesměrování a také objekty request a response. Najprve nastavíme HTTP stav na SC_SEE_OTHER (tedy právě 303) a poté nastavíme hodnotu HTTP hlavičky Location na relativní adresu pro přesměrování. Na začátek této hlavičky potřebujeme zadat kontextovou kořenovou URL aplikace (tu jsme zadali při tvorbě projektu a je mi možné měnit v souboru context.xml). Díky tomuto nastavení základní URL bude naše aplikace snadno přenostitelná například na produkční server.

/pridat

Na adrese /pridat probíhá ukládání nového zápisku (podobně jako v minulém díle).

if(adresa.equals("/pridat")) {
    String nadpis = request.getParameter("nadpis");
    String obsah = request.getParameter("obsah");
    if(!nadpis.isEmpty() && !obsah.isEmpty()){
        zapisky.add(new Zapisek(nadpis, obsah));
        presmeruj(request, response, "/");
    }
    else {
        presmeruj(request, response, "/?upozorneni=True");
    }          
}

Nejprve z requestu převezmeme nadpis a obsah zápisku. Pokud jsou obě pole vyplněná, zapíšeme nový zápisek do seznamu a uživatele přesměrujeme na úvodní stránku. Pokud nejsou vstupy vyplňeny, přesměrujeme uživatele na úvodní stránku a navíc přidáme do adresy parametr ?upozorneni=True, který vybídne view k vypsání upozornění.

/ulozitupravy

Na této adrese budeme ukládat změny provedené ze stránky /upravit. Postup je podobný jako u přidávání nového příspěvku, nyní ale navíc přijímáme index upravovaného příspěvku. Pokud jsou všechna pole vyplněna, nová data se uloží na místo již existujícího zápisku a proběhne přesměrování na úvodní stránku. Pokud zůstalo některé pole nevyplněno, bude uživatel přesměrován na stránku úpravy zápisku a do adresy přidáme parametr vybízející k vypsaní upozornění.

else if(adresa.equals("/ulozitupravy")){
    int index = Integer.parseInt(request.getParameter("index"));
    String nadpis = request.getParameter("nadpis");
    String obsah = request.getParameter("obsah");
    if(!nadpis.isEmpty() && !obsah.isEmpty()){
        zapisky.set(index, new Zapisek(nadpis, obsah));
        presmeruj(request, response, "/");
    }
    else {
        presmeruj(request, response, "/upravit?index=" + index + "&upozorneni=True");
    }
}

/smazat

Na adrese /smazat se převezme index zápisku, provede se jeho smazání ze seznamu a proběhne přesměrování na úvodní stránku.

else if(adresa.equals("/smazat")){
    int index = Integer.parseInt(request.getParameter("index"));
    zapisky.remove(index);
    presmeruj(request, response, "/");
}

Závěr

To je ke controlleru vše. V dalším navazujícím díle si vytvoříme příslušné view-y, základní šablonu stránek a předvedeme další funkce z knihovny JSTL.

Zdrojové kódy aplikace naleznete na GitHubu: https://github.com/PetrHoracek/JavaNaWeb

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

4.10.2018 21:30 /Ondřej Čečák
LinuxDays 2018 již tento víkend, registrace je otevřená.
Přidat komentář

18.9.2018 23:30 /František Kučera
Zářijový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 20. 9. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář

9.9.2018 14:15 /Redakce Linuxsoft.cz
20.9.2018 proběhne v pražském Kongresovém centru Vavruška konference Mobilní řešení pro business. Návštěvníci si vyslechnou mimo jiné přednášky na témata: Nejdůležitější aktuální trendy v oblasti mobilních technologií, správa a zabezpečení mobilních zařízení ve firmách, jak mobilně přistupovat k informačnímu systému firmy, kdy se vyplatí používat odolná mobilní zařízení nebo jak zabezpečit mobilní komunikaci.
Přidat komentář

12.8.2018 16:58 /František Kučera
Srpnový pražský sraz spolku OpenAlt se koná ve čtvrtek – 16. 8. 2018 od 19:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát jsou tématem srazu databáze prezentaci svého projektu si pro nás připravil Standa Dzik. Dále bude prostor, abychom probrali nápady na využití IoT a sítě The Things Network, případně další témata.
Přidat komentář

16.7.2018 1:05 /František Kučera
Červencový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 7. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát bude přednáška na téma: automatizační nástroj Ansible, kterou si připravil Martin Vicián.
Přidat komentář

18.6.2018 0:43 /František Kučera
Červnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 21. 6. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: F-Droid, aneb svobodný software do vašeho mobilu. Kromě toho budou k vidění i vývojové desky HiFive1 se svobodným/otevřeným čipem RISC-V.
Přidat komentář

23.5.2018 20:55 /Ondřej Čečák
Od pátku 25.5. proběhne na Fakultě informačních technologií ČVUT v Praze openSUSE Conference. Můžete se těšit na spostu zajímavých přednášek, workshopů a také na Release Party nového openSUSE leap 15.0. V na stejném místě proběhne v sobotu 26.5. i seminář o bezpečnosti CryptoFest.
Přidat komentář

20.5.2018 17:45 /Redakce Linuxsoft.cz
Ve čtvrtek 31. května 2018 připravuje webový magazín BusinessIT ve spolupráci s Best Online Média s.r.o. pátý ročník odborné konference Firemní informační systémy 2018. Akce proběhne v kongresovém centru Vavruška (palác Charitas), Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00 hod. dopoledne do cca 15 hod. odpoledne. Konference je zaměřena na efektivní využití firemních informačních systémů a na to, jak plně využít jejich potenciál. Podrobnější informace na webových stránkách konfrence.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

5.10.2018 17:12 / Jakub Kuljovsky
Re: Jaký kurz a software by jste doporučili pro začínajcího kodéra?

20.9.2018 10:04 / Jan Ober
Jaký kurz a software by jste doporučili pro začínajcího kodéra?

20.9.2018 10:00 / Jan Ober
Re: Gimp

20.2.2018 18:48 / Ivan Majer
portal

20.2.2018 15:57 / Jan Havel
Jak využíváte služby cloudu v podnikání?

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2018) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze