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 8176×

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ů

15.5.2017 23:50 /František Kučera

Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt, který se bude konat ve čtvrtek 18. května od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).


Přidat komentář

12.5.2017 16:42 /Honza Javorek
PyCon CZ, česká konference o programovacím jazyce Python, se po dvou úspěšných ročnících v Brně bude letos konat v Praze, a to 8. až 10. června. Na konferenci letos zavítá např. i Armin Ronacher, známý především jako autor frameworku Flask, šablon Jinja2/Twig, a dalších projektů. Těšit se můžete na přednášky o datové analytice, tvorbě webu, testování, tvorbě API, učení a mentorování programování, přednášky o rozvoji komunity, o použití Pythonu ve vědě nebo k ovládání nejrůznějších zařízení (MicroPython). Na vlastní prsty si můžete na workshopech vyzkoušet postavit Pythonem ovládaného robota, naučit se učit šestileté děti programovat, efektivně testovat nebo si v Pythonu pohrát s kartografickým materiálem. Kupujte lístky, dokud jsou.
Přidat komentář

2.5.2017 9:20 /Eva Rázgová
Putovní konference československé Drupal komunity "DrupalCamp Československo" se tentokrát koná 27. 5.2017 na VUT FIT v Brně. Můžete načerpat a vyměnit si zkušenosti z oblasti Drupalu 7 a 8, UX, SEO, managementu týmového vývoje, využití Dockeru pro Drupal a dalších. Vítáni jsou nováčci i experti. Akci pořádají Slovenská Drupal Asociácia a česká Asociace pro Drupal. Registrace na webu .
Přidat komentář

1.5.2017 20:31 /Pavel `Goldenfish' Kysilka
PR: 25.5.2017 proběhne v Praze konference na téma Firemní informační systémy. Hlavními tématy jsou: Informační systémy s vlastní inteligencí, efektivní práce s dokumenty, mobilní přístup k datům nebo využívání cloudu.
Přidat komentář

15.4.2017 15:20 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě IoT a radiokomunikace? Přijď na sraz spolku OpenAlt, který se bude konat ve středu 19. dubna od 18:30 v Šenkovně (Sokolská 60, Praha 2).
Přidat komentář

5.3.2017 19:12 /Redakce Linuxsoft.cz
PR: 23. března proběhne v Praze konferenci na téma Cloud computing v praxi. Hlavními tématy jsou: Nejžhavější trendy v oblasti cloudu a cloudových řešení, Moderní cloudové služby, Infrastruktura současných cloudů, Efektivní využití cloudu, Nástrahy cloudových řešení a jak se jim vyhnout.
Přidat komentář

27.2.2017 22:12 /František Kučera
Pozvánka na 137. sraz OpenAlt – Praha: Tentokrát jsme si pro vás připravili neobvyklou akci. Ve středu 1.3. v 17:30 nás přivítá sdružení CZ.NIC ve svých prostorách v Milešovské ulici číslo 5 na Praze 3, kde si pro nás připravili krátkou prezentaci jejich činnosti. Následně navštívíme jejich datacentrum pod Žižkovskou věží. Provedou nás prostory, které jsou běžnému smrtelníkovi nedostupné!
Po ukončení prohlídky se všchni odebereme do hostince U vodoucha, Jagelonská 21, Praha 3 pochutnat si na některém z vybraných piv či dát si něco na zub. Rezervaci máme od 19:30, heslo je OpenAlt.
Ale pozor! Do prostor datového centra máme omezený přístup, dostane se tam pouze 10 lidí! Takže kdo přijde dříve, ten má přednost, a občanky s sebou! Kdo nebude chtít na prohlídku datového centra, může se pomalu přesunout do hostince U vodoucha a u nepřeberné nabídky piv počkat na ostatní.
Přidat komentář

18.1.2017 0:49 /František Kučera
Členové a příznivci spolku OpenAlt se pravidelně schází v Praze a Brně. Fotky z pražských srazů za uplynulý rok si můžete prohlédnout na stránkách spolku. Příští sraz se koná už 19. ledna – tentokrát je tématem ergonomie ovládání počítače – tzn. klávesnice, myši a další zařízení. Také budete mít příležitost si prohlédnout pražský hackerspace Brmlab.
Přidat komentář

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

> Poslední diskuze

11.5.2017 23:32 / lelo
Re: Problém se správcem balíčků

11.5.2017 5:45 / davd mašek
Re: Problém se správcem balíčků

10.5.2017 22:54 / lelo
Re: Problém se správcem balíčků

10.5.2017 22:19 / davd mašek
Problém se správcem balíčků

17.4.2017 19:15 / Jakub shoop
chyba

Více ...

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