Lukáš Knápek - Nullpointer.cz - RSS odběr Dexempo pro váš kód http://www.nullpointer.cz/ Webová aplikace v Javě od A do Z – Hello world ve Struts2 + zobrazení ve webovém prohlížeči (3.díl) Thu, 19 Sep 2013 12:04:54 GMT http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-hello-world-ve-struts2-zobrazeni-ve-webovem-prohlizeci-3-dil <!-- by Texy2! --> <p>V předchozích dílech tohoto seriálu jsme si připravili v Eclipse java projekt a nakonfigurovali Maven2 pro integraci externích knihoven do našeho projektu. Pro potřeby tohoto dílu budeme potřebovat do našeho projektu připojit <strong>framework Struts2.</strong> V minulém díle jsme tuto závislost do pom.xml již přidávali, přesto pro jistotu ještě jednou:</p> <p><strong>Obsah souboru pom.xml</strong></p> <pre class="html"><code>&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt; &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; &lt;groupId&gt;cz.atax&lt;/groupId&gt; &lt;artifactId&gt;base-maven&lt;/artifactId&gt; &lt;packaging&gt;pom&lt;/packaging&gt; &lt;version&gt;1.0&lt;/version&gt; &lt;properties&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.apache.struts&lt;/groupId&gt; &lt;artifactId&gt;struts2-core&lt;/artifactId&gt; &lt;version&gt;2.3.8&lt;/version&gt; &lt;/dependency&gt; &lt;/dependencies&gt; &lt;/project&gt;</code></pre> <h3>Cíl</h3> <p>Zadat do webového prohlížeče konkrétní adresu, např. <strong>localhost:8095/Nu­llpointer/hello­World</strong>, která povede na stránku, kde nebude nic jiného než hláška Hello World.</p> <h3>Postup</h3> <ol> <li>Vytvořit potřebné konfigurační soubory: <p>a. struts.xml</p> <p>b. web.xml</p> </li> <li>Vytvořit potřebné soubory pro vypsání hlášky: <p>a. java třídu HelloWorldActi­on.java</p> <p>b. jsp soubor helloWorld.jsp</p> </li> <li>Zprovoznit lokální server Tomcat a spustit na něm naši aplikaci – to vše přímo v Eclipsech</li> </ol> <h2>Ad 1) a. struts.xml</h2> <p>Nejdříve obsah souboru a posléze vysvětlím, o co tam jde:</p> <p><strong>Obsah souboru struts.xml</strong></p> <pre class="html"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"&gt; &lt;struts&gt; &lt;package name="nullpointer" extends="struts-default"&gt; &lt;action name="helloWorld" method="helloWorldMethod" class="cz.nullpointer.helloWorld.HelloWorldAction"&gt; &lt;result name="success"&gt;helloWorld.jsp&lt;/result&gt; &lt;/action&gt; &lt;/package&gt; &lt;/struts&gt;</code></pre> <p>Soubor uložíme do source folder <strong>src/main/resou­rces</strong> pod jménem <strong>struts.xml.</strong> Tedy pravé tlačítko myši na folder src/main/resources v menu vybereme <strong>New…/Other…/Xml/XML file</strong> a do souboru zkopírujeme obsah uvedený výše. Soubor struts.xml je základ frameworku Struts2 a jeho pochopení je základ, který nám ovšem bude stačit i na mnohem složitější úkoly než Hello World. Důležitý je tento odstaveček:</p> <pre class="html"><code>&lt;action name="helloWorld" method="helloWorldMethod" class="cz.nullpointer.helloWorld.HelloWorldAction"&gt; &lt;result name="success"&gt;helloWorld.jsp&lt;/result&gt; &lt;/action&gt;</code></pre> <p>Takže popořadě:</p> <ul> <li><strong>name=„helloWor­ld“:</strong> pokud bude požadavek v prohlížeči localhost:8095/Nu­llpointer/<strong>hello­World</strong>, bude se používat toto mapování.</li> <li><strong>method=„hello­WorldMethod“ a class=„cz.nullpo­inter.helloWor­ld.HelloWorldAc­tion“&gt;:</strong> pro zpracování požadavku se bude volat metoda helloWorldMethod v java třídě cz.nullpointer­.helloWorld.He­lloWorldAction (zatím nemáme vytvořené, viz níže)</li> <li><strong>&lt;result name=„success“&gt;he­lloWorld.jsp&lt;/re­sult&gt;:</strong> vrátí-li metoda helloWorldMethod řetězec „success“ zobrazí se v prohlížeči jsp soubor helloWorld.jsp (což je v podstatě takové obohacené html, viz níže).</li> </ul> <h2>Ad 1) b. web.xml</h2> <p>Pokud jste správně prošli předchozími kroky tohoto seriálu, měli byste mít již soubor <strong>web.xml</strong> ve vašem projektu, konkrétně ve složce <strong>WEB-INF</strong>. Pokud ne, vytvořte jej. Smažte jeho případný obsah a vložte do něj tento:</p> <p><strong>Obsah souboru web.xml</strong></p> <pre class="html"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"&gt; &lt;filter&gt; &lt;filter-name&gt;struts2&lt;/filter-name&gt; &lt;filter-class&gt;org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;struts2&lt;/filter-name&gt; &lt;url-pattern&gt;/*&lt;/url-pattern&gt; &lt;/filter-mapping&gt; &lt;/web-app&gt;</code></pre> <p>V tomto souboru lze provádět spoustu různých užitečných konfigurací, to však není předmětem našeho seriálu. Stručně se dá říct, že jsme zde řekli, ať všechny požadavky v url zpracovává Struts2 (a tím přijdou na řadu struts.xml) a to nám (nejen) pro Hello World bohatě stačí.</p> <h2>Ad 2) a. Java třída HelloWorldActi­on.java</h2> <p>V source folderu <strong>src/main/java</strong> vytvoříme <strong>package cz.nullpointer­.helloWorld</strong> a v něm třídu <strong>HelloWorldActi­on.java.</strong> Do něj zadáme tento obsah :</p> <p><strong>Obsah souboru HelloWorldActi­on.java</strong></p> <pre class="java"><code>package cz.nullpointer.helloWorld; import com.opensymphony.xwork2.ActionSupport; public class HelloWorldAction extends ActionSupport { public String helloWorldMethod() { return SUCCESS; } }</code></pre> <p>Důležitá je metoda:</p> <pre class="java"><code>public String helloWorldMethod() { return SUCCESS; }</code></pre> <p>Tato metoda nedělá nic jiného, než že vrací String konstantu SUCCESS, na kterou máme namapováno naše jsp (ještě není vytvořené, viz níže). Nyní není potřeba, aby se zde dělo cokoliv jiného, ale v běžném vývoji zde samozřejmě probíhá načítání potřebných dat pro zobrazení jsp (stránky), typicky načítání dat z databáze. Asi není třeba dodávat, že tohle je přesně ta třída a metoda (HelloWorldAction a helloWorldMethod), kterou jsme zmiňovali výše v našem struts.xml (viz bod 1) a.)</p> <h2>Ad 2) b. jsp soubor helloWorld.jsp</h2> <p>Než vytvoříme <strong>jsp helloWorld.jsp</strong>, je důležité vědět, kde je root, kam se struts2 defaultně dívá po jsp a kam tedy máme jsp soubor uložit. Možná jste si všimli, že ve struts.xml jsme uvedli pouze helloWorld.jsp, žádnou cestu, žádné složky. To znamená, že se jsp bude hledat v defaultní složce, což je ../WEB-INF (nadřazený WEB-INF, čili jsp musí být ve stejné složce jako je složka WEB-INF). Tam se budou hledat v prvé řadě jsp soubory. V konfiguraci Struts2 lze samozřejmě tuto cestu změnit, ale tím se nyní nebudeme zabývat. Vytovříme tedy soubor helloWorld.jsp s tímto obsahem:</p> <p><strong>Obsah souboru helloWorld.jsp</strong></p> <pre class="html"><code>&lt;%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%&gt; &lt;%@ taglib prefix="s" uri="/struts-tags"%&gt; &lt;h1&gt;Hello World!&lt;/h1&gt;</code></pre> <p>Za komentář zde stojí možná jen &lt;%@ taglib prefix=„s“ uri=„/struts-tags“%&gt;. Tento zápis nám říká, že budeme v našem jsp používat struts2 tagy (některé nejtypičtější si ukážeme v dalším díle našeho seriálu), v současném jsp žádné Struts2 tagy nepoužíváme, vypisujeme jen Hello World v html nadpisu h1, ale radši jsem to uvedl již teď, ať na to pak nezapomeneme.</p> <h2>Ad 3) Zprovoznit lokální server Tomcat a spustit na něm naši aplikaci – to vše přímo v Eclipse</h2> <p>Nejdřív musíme <strong>stáhnout Tomcat na adrese <a href="http://tomcat.apache.org/">http://tomcat.apache.org/</a></strong> je v levé menu sekce download. Stáhněte nejnovější verzi (v tomto článku používám verzi Tomcat 7) a uložte jej na disk. V současné době lze již stáhnout verzi Tomcatu 8, ale zdá se, že jej Eclipse ve verzi jakou používám (viz předchozí díl seriálu) nepodporuje. Nyní přidáme Tomcat do Eclipse. V Eclipse dáme v menu <strong>Window/Show view…/Other/Ser­ver/Servers</strong> a tím si v prostředí trvale zobrazíme záložku Servers (záložka se ve spodní části vývojového prostředí). V ní by mělo být napsáno zhruba následující: <strong>No servers available. Define a new server from the new server wizard…</strong> Klikneme tedy na odkaz new server wizard. Objeví se dialogové okno, kde zvolíme Apache/Tomcat [VERZE] a klikneme na tlačítko Next. Eclipse bude chtít vědět cestu k Tomcatu, zadejte tedy umístění, kam jste Tomcat před chvíli nahráli. Zase Next. Nyní chce Eclipse vědět, které projekty chcete pod server umístit. Ve sloupci Available by měl být pouze jeden, náš projekt, klikněte na něj a pak klikněte na tlačítko Add &gt;. Projekt by se měl přesunout do sloupce Configured. Nyní můžeme dát Finish.</p> <p>V záložce Servers v Eclipse by již nyní měl být vidět přidaný server. Já tam mám označení <strong>Tomcat v7.0 Server at localhost [Stopped, Synchronized]</strong>. Pokud nám nic neběží na portu 8080, můžeme vše nechat při defaultním nastavení, jinak musíme port změnit. Navrhuji v každém případě radši port změnit, abychom se vyhnuli současným a případně i budoucím konfliktům. Klikněte dvakrát na server Tomcat v7.0 Server at localhost… a objeví se konfigurace. Zde nalevo najdeme sekce <strong>Ports</strong>, kde je tabulka používaných portů, kde je mimo jiné i <strong>http/1.1 a port number 8080</strong>. Ten změníme na něco jiného, třeba <strong>8095</strong>, ať to máte stejné jak v tomto příkladu a <strong>uložíme změny pomocí CTRL+S.</strong></p> <p>Dále je velmi důležité nastavit projektu správný <strong>context root.</strong> Nyní už jsme kousek od toho zadat do prohlížeče toto: localhost:8095/Nu­llpointer/hello­World a zobrazit si nadpis Hello World! (tedy naše jsp) v prohlížeči. Považuji za důležité si tuto adresu ještě krátce rozebrat.</p> <ul> <li><strong>localhost:8095</strong> – localhost je default a 8095 je port, který jsme před chvíli nastavovali v Tomcat konfiguraci.</li> <li><strong>Nullpointer</strong> – to jsme zatím nikde nenastavovali, to je právě onen context root. Dejme pravé tlačítko myši na project, zvolme v menu Properties a najděme v levém menu Web project settings a klikněme na tuto položku. Zde nastavíme Context root, můžeme dát Nullpointer, jak používám v tomto příkladě.</li> <li><strong>helloWorld</strong> – máme nastaveno ve struts.xml (viz výše, řádek <em>&lt;action name=„helloWorld“</em>)</li> </ul> <p><strong>Důležité – Deployment Assembly:</strong> nyní je ještě potřeba překontrolovat jednu věc. Klikněte pravým tlačítkem na projekt (v levém sloupečku) a zvolte <strong>Properties/De­ployment Assembly.</strong> V tabulce byste měli mít ve sloupci Source 4 záznamy: <strong>/src/main/java, /src/main/resou­rces, /src/test/java, /WebContent a Maven Dependencies.</strong> Ve sloupci Deploy Path byste měli mít (popořadě) následující: <strong>WEB-INF/classes (3×), /, WEB-INF/lib.</strong> O co tu jde? Tady se říká, do jaké struktury má Eclipse zbuildovat náš projekt. <strong>Nemusíte mít přesně stejnou strukturu, jakou jsem tady nastínil.</strong> Záleží např. na tom, jakou používáte Eclipse perspektivu, jakou máte verzi Eclipse (viz předchozí díly), jak moc důsledně jste dodrželi kroky z předchozích dílů našeho seriálu apod. Každopádně ve <strong>WEB-INF/classes</strong> by měly být <strong>java soubory + struts.xml</strong> (já jej mám v src/main/re­sources), <strong>Maven Dependencies</strong> ve <strong>WEB-INF/lib</strong> a v kořenové složce <strong>/</strong> by měla být složka, kde máme <strong>jsp soubory</strong> (v našem případě jeden jsp soubor helloWorld.jsp) a později třeba javascriptové knihovny a css. Pokud vaši strukturu nemáte v tomto duchu, pomocí tlačítka Add.. doplňte potřebné věci. Hlavně Maven Dependencies zde často chybí.</p> <p>Nyní nezbývá nic jiného, než pustit server a modlit se. Server pustíme tak, že v Eclipse v záložce Servers klikneme pravý tlačítkem myši na <strong>Tomcat v7.0 Server at localhost [Stopped, Synchronized]</strong> a zvolíme v menu <strong>Start</strong> nebo <strong>Debug</strong> (pro tuto chvíli je jedno co). Během pár vteřin by se měl server spustit, což uvidíme v Eclipse v záložce Console. Neměla by se tam objevit žádná chyba (Exception).</p> <p>Zkuste si nyní spusti prohlížeč a zadat do adresního řádku <strong>localhost:8095/Nu­llpointer/hello­World. Vidíte text Hello World? Gratuluji, povedl se vám malý zázrak!</strong> A také jste úspěšně dokončili tuto část seriálu. Můžete si klidně vyzkoušet, že do jsp můžete vkládat libovolné html i css, jakoby to byl opravdu obyčejný html soubor.</p> <p>Většinou se to hned napoprvé nepovede. Pokud se nepodařilo, pokusím se v následujícím odstavci poukázat na nejčastější chyby.</p> <h3>Nepovedlo se to rozjet?</h3> <p>V tomto případě po zadání adresy <strong>localhost:8095/Nu­llpointer/hello­World</strong> se určitě objeví chyba 404, že stránku nelze zobrazit.</p> <ol> <li>Zkontrolujte, že opravdu máte správně nastavený port (localhost:8095), context root (Nullpointer) a akci ve struts.xml (helloWorld, viz řádek &lt;action name=„helloWorld“))</li> <li>Zkontrolujte v Eclipse konzoli, že se neobjevují žádné Exception. Pokud ano, zkuste následující: <ul> <li>zavřít a otevřít projekt (pravé tlačítko na projekt, <strong>Close Project/Open Project</strong>)</li> <li>dejte pravé tlačítko na projekt a zvolte <strong>Refresh</strong></li> <li>dejte pravé tlačítko na server a zvolit možnosti <strong>Clean Tomcat Work Directory…</strong> a pak také ve stejném menu <strong>Clean…</strong></li> <li>v Eclipse nahoře v menu dejte <strong>Project/Clean/Cle­an all projects</strong> a rovnou zkontrolujte, jestli máte v nabídce Project zaškrtnuté <strong>Build Automatically</strong></li> <li>zkuste <strong>vypnout a znovu zapnout Eclipse</strong> a znovu provést <strong>refresh a cleanování.</strong> </li> </ul> </li> <li><strong>Výjímka SEVERE: Exception starting filter struts2 java.lang.Clas­sNotFoundExcep­tion: org.apache.strut­s2.dispatcher­.ng.filter.Strut­sPrepareAndExe­cuteFilter:</strong> zkontrolujte, že máte v projektu (v levém sloupečku v Eclipse) Maven Dependencies. Pokud nemáte, nezafungoval maven a asi máte špatně pom.xml nebo špatně instalovaný maven plugin (viz předchozí díl tohoto seriálu). Pokud tam Maven Dependencies máte, zkuste v Eclipse pomocí CTRL+T vyhledat chybějící třídu org.apache.strut­s2.dispatcher­.ng.filter.Strut­sPrepareAndExe­cuteFilter. Pokud jste tuto třídu nenalezli, nejspíš vám v pom.xml chybí závislost na struts2 (viz začátek tohoto dílu). Pokud jste třídu nalezli, nejspíš je problém v chybějících Maven Dependencies v Deployment Assembly (viz pár odstavců výše).</li> <li>Pokud se stále Exception při startu objevuje, tak asi nezbývá než <strong>googlit</strong> nebo můžete napsat (např. do komentářů pod tento článek) váš problém (např. jakou Exception vám to háže při startu) a já vám mohu zkusit poradit a současně tím poté zkvalitnit tento odstavec.</li> </ol> <p>Můžete také zkusit si na disku najít (po spuštění serveru, ať už úspěšném nebo neúspěšném) složku <strong>org.eclipse.wst­.server.core</strong>. Měla by být ve vašem workspace v cestě <strong>[CESTA_K_VASE­MU_WORKSPACE]/­.metadata/.plu­gins/ org.eclipse.wst­.server.core.</strong> Pokud tuto složku otevřete měla by tam být složka <strong>tmp0/ wtpwebapps</strong> a v ní složka <strong>Nullpointer</strong> (náš context root, viz výše). V této složce bychom měli najít další dvě složky <strong>Meta-inf</strong> a <strong>Web-inf</strong> a také naše jsp <strong>helloWorld.jsp.</strong> Sem totiž Eclipse zbuildoval (pokud se vše podařilo) náš projekt. Ještě můžeme zkontrolovat na tom stejném místě, že ve složce <strong>Web-inf/classes/cz/nu­llpointer/hello­World/</strong> je zkompilovaná třída <strong>HelloWorldActi­on.class.</strong> Pokud tohle vše vidíme, tak build a deploy pod server proběhl v pořádku a chyba by měla být v zadávané adrese (špatný port, špatný název contextRoot, špatný název akce). Pokud to tam nevidíte, proběhl špatně build, nejspíš z důvodu nějaké Exception při startu serveru (vidíme v konzoli). Řešení Exception viz výše (bod 2.).</p> <h3>Závěr</h3> <p>Myslím, že to nejhorší máme v tomto seriálu za sebou a teď už přejdeme od nudných konfigurací k zábavnějším věcem. Ještě nás samozřejmě čeká konfigurace Springu a Hibernatu, ale to až přespříští díl. Příští díl si ukážeme základní využití Struts2 frameworku a seznámíme se s nejpoužívanějšími struts2 tagy.</p> http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-hello-world-ve-struts2-zobrazeni-ve-webovem-prohlizeci-3-dil Webová aplikace v Javě od A do Z – Maven plugin pro Eclipse a přidání Struts2 do projektu (2. díl) Thu, 10 Jan 2013 11:31:05 GMT http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-maven-plugin-pro-eclipse-a-pridani-struts2-do-projektu-2-dil <p>V předchozím díle tohoto seriálu jsme si připravili v Eclipse java projekt. Nyní do projektu přidáme užitečné nástroje a frameworky, a to především Maven a Struts2.</p> <p><a href="http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-eclipse-priprava-prostredi-a-zalozeni-projektu-1-dil">V předchozím díle tohoto seriálu</a> jsme si připravili v Eclipse java projekt. Nyní do projektu přidáme užitečné nástroje a frameworky, a to především <strong>Maven a Struts2</strong>, později pak Spring a Hibernate. Java aplikace jsou z velké části postavené na externích knihovnách, tzv. knihovnách třetích stran, což jsou prostě hotové a vyladěné programy jiných programátorů, které nám mají ulehčit práci. Proč strávit spoustu času programováním věcí, které už někdo před námi udělal? Jedná se především o:</p> <p><strong>1) Frameworky:</strong> výrazně nám usnadňují psaní java a web kódu, protože spoustu nutných režijních věcí udělají za nás. Často tak odpadá „byrokracie“ okolo programování aplikace, o kterou se postará framework za nás. Také nás většinou nenásilně donutí psát slušně strukturovanou aplikaci, např. aby se držela architektura MVC, případně dodržovaly jiné, praxí ověřené programovací standardy. Je to, jako bychom byli zvoleni ministry a na běžnou nudnou administrativní práci bychom si najali šikovné úředníky. Ti mají znalosti o současných zákonech a jejich novelách a o nutných administrativních činnostech potřebných pro správný chod ministerstva. My se pak můžeme zvesela věnovat ministrování :-)</p> <p><strong>2) Utilitní knihovny:</strong> poskytují různou užitečnou funkcionalitu, kterou můžeme využívat v naší aplikaci, aniž bychom si ji museli sami psát. V tomto seriálu budeme nejspíš později využívat pouze knihovnu Joda time pro práci s datumy. Takže naše výsledná webová aplikace bude souhrn těchto tří částí:</p> <ul> <li>našeho vlastního kódu</li> <li>frameworků</li> <li>utilitních knihoven</li> </ul> <p>Nástroj, který umí tyto tři části slepit v jeden fungující celek se jmenuje <strong>Maven</strong>.</p> <h3>Maven</h3> <p>Maven je nástroj pro buildování java aplikací a kromě toho umí spoustu dalších věcí. My po něm ale v našem seriálu chtít jediné. Aby vzal naši aplikaci napsanou v javě a v hml, přidal k ní všechny potřebné závislosti na knihovnách třetích stran (tedy frameworky a utilitní knihovny) a vytvořil jeden tzv. WAR soubor, který si potom budeme moci spustit na lokálním serveru a následně se ve webovém prohlížeči podívat na výsledek naší práce. A nyní již prakticky. Asi nejjednodušší a nejpohodlnější způsob jak vyvíjet, je <strong>nainstalovat si do Eclipse maven plugin</strong> a nechat Eclipse, ať pomocí mavenu automaticky builduje naší aplikaci. Prakticky to pak bude vypadat tak, že budeme psát v Eclipse kód a výsledky rovnou zobrazovat ve webovém prohlížeči.</p> <h3>Maven plugin (m2eclipse)</h3> <p>Maven pluginů je víc, já budu používat <strong>m2eclipse</strong>. Do Eclipse jej nainstalujeme velmi jednoduše:</p> <ol> <li>Otevřeme Eclipse a menu vybereme možnost Help/Eclipse Marketplace.</li> <li>V okně nic nebudeme měnit, jen do políčka Search dáme vyhledat m2eclipse.</li> <li>Mezi nalezenými záznamy by měl být Maven integration for Eclipse (přesně takovýto název, neinstalujte žádný WTP, for Incubation apod.)</li> <li>U toho záznamu stiskneme tlačítko Install a nainstalujeme plugin.</li> <li>Nakonec se Eclipse bude chtít restartovat, takže mu to povolíme a plugin je připraven k používání.</li> </ol> <p>Ještě je důležité našemu vytvořenému projektu (viz první díl tohoto seriálu) říct, že má maven používat. To se dělá takto:</p> <ul> <li>v Eclipse klikněte pravým tlačítkem myši na projekt (levý sloupec)</li> <li>zvolte nabídku <strong>Configure/Convert to maven project</strong></li> </ul> <h3>Maven – Pom.xml</h3> <p>V mavenu všechno začíná a končí u souboru <strong>pom.xml.</strong> V něm vyjmenujeme všechny java knihovny, na kterých bude náš projekt záviset (viz výše). To je jediné, co se po nás chce. Maven je pro nás automaticky stáhne z internetu, připojí je k našemu projektu a my je můžeme začít používat. Vytvořme si nyní v Eclipse nový soubor pom.xml:</p> <ul> <li>pravé tlačítko myši na název projektu (v Eclipse v pravém sloupci, viz minulý díl seriálu), nabídka New/Other/Xml/Xml f­ile.</li> <li>soubor pojmenujte jako pom.xml a dejte finish.</li> </ul> <p>Do pom.xml dáme pro začátek tento obsah:</p> <pre class="xml"><code>&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt; &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; &lt;groupId&gt;cz.nullpointer&lt;/groupId&gt; &lt;artifactId&gt;base-maven&lt;/artifactId&gt; &lt;packaging&gt;pom&lt;/packaging&gt; &lt;version&gt;1.0&lt;/version&gt; &lt;properties&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;/dependencies&gt; &lt;/project&gt;</code></pre> <p>Mezi tagy &lt;dependencies&gt;&lt;/de­pendencies&gt; budeme dávat zmiňované závislosti, jak si nyní ukážeme. První externí knihovnou, kterou budeme v našem projektu využívat (a závislost na ní tedy uvedeme v pom.xml), je Struts2 framework.</p> <h3>Struts2 – integrace do projektu pomocí Mavenu</h3> <p>Struts2 je framework, který nám významně usnadní tvorbu java webových aplikací. Abychom ho mohli začít používat, musíme jej nejdříve přidat k závislostem našeho projektu, tedy do souboru pom.xml, který jsme si vytvořili před chvílí. Celý soubor pom.xml pak bude vypadat takto:</p> <pre class="xml"><code>&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt; &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; &lt;groupId&gt; cz.nullpointer&lt;/groupId&gt; &lt;artifactId&gt;base-maven&lt;/artifactId&gt; &lt;packaging&gt;pom&lt;/packaging&gt; &lt;version&gt;1.0&lt;/version&gt; &lt;properties&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.apache.struts&lt;/groupId&gt; &lt;artifactId&gt;struts2-core&lt;/artifactId&gt; &lt;version&gt;2.3.8&lt;/version&gt; &lt;/dependency&gt; &lt;/dependencies&gt; &lt;/project&gt;</code></pre> <p>Nyní mavenu říkáme, že v našem projektu budeme chtít používat struts2 verzi 2.3.8 (v době psaní tohoto článku nejaktuálnější). Jakmile soubor pom.xml uložíme, měl by maven plugin v Eclipse stáhnout tuto závislost a přiřadit ji k našemu projektu. To poznáme tak, že v projektu <strong>uvidíme kontejner Maven Dependencies</strong>, do které nám bude maven dávat všechny jar knihovny, které jsou potřeba k závislostem, které jsme uvedli v souboru pom.xml. Měl by se objevit hned pod kontejner JRE System Library (JDK…), tedy pod Javou, kterou jsme do projektu přidali v minulém díle.</p> <p>Může se bohužel stát, že se však kontejner Maven Dependencies v projektu neobjeví, což se stalo i mně v době psaní tohoto seriálu. <strong>Nejpravděpodob­nějším viníkem je špatný obsah souboru .classpath.</strong></p> <h3>Maven plugin a .classpath</h3> <p>V první řadě zkontrolujte, že jste zkonvertovali svůj projekt na maven projekt. To se dělá pravým tlačítkem na projekt, v nabídce vyberte <strong>Configure/Convert to maven projekt</strong> (v tomto článku jsme to již dělali výše, uvádím jen pro úplnost). V ikonce projektu by se mělo objevit malé modré M. Pokud se přesto kontejner Maven Dependencies neobjevuje, problém je s nejvyšší pravděpodobností v obsahu souboru <strong>.classpath</strong>, který obsahuje každý Eclipse projekt. Tento soubor neuvidíme v Eclipse, musíme si náš projekt najít na disku, např. pomocí Total Commandera nebo průzkumníka. Můj .classpath vypadá nyní následovně:</p> <pre class="xml"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;classpath&gt; &lt;classpathentry kind="src" path="src/main/java"/&gt; &lt;classpathentry kind="src" path="src/main/resources"/&gt; &lt;classpathentry kind="src" path="src/test/java"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/&gt; &lt;classpathentry kind="output" path="build/classes"/&gt; &lt;/classpath&gt;</code></pre> <p>Což je problém, protože tu vůbec není maven a proto se nestahují potřebné závislosti (v našem případě Struts2).Změňte obsah souboru .classpath na:</p> <pre class="xml"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;classpath&gt; &lt;classpathentry kind="src" output="target/classes" path="src/main/java"/&gt; &lt;classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/&gt; &lt;classpathentry kind="src" output="target/test-classes" path="src/test/java"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/&gt; &lt;classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"&gt; &lt;attributes&gt; &lt;attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/&gt; &lt;/attributes&gt; &lt;/classpathentry&gt; &lt;classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/&gt; &lt;classpathentry kind="output" path="target/classes"/&gt; &lt;/classpath&gt;</code></pre> <p><strong>Samozřejmě pokud máte jinou strukturu projektu než já, musíte soubor .classpath patřičně upravit.</strong> Jedná se o source folders, v příkladu jsou to <strong>src/main/java, src/test/java a src/main/resources</strong> (viz předchozí díl tohoto seriálu, kde jsme takto zakládali projekt). Nyní se vraťte do Eclipse a mělo by stačit zavřít a znovu otevřít projekt (pravé tlačítko myši na projekt a nabídka Close project, posléze Open project), můžete předtím pro jistotu ještě pomocí F5 projekt refreshnout. <strong>Nyní by se již v projektu měl objevit kontejner Maven Dependencies</strong> (pozor, je vidět jen v Eclipse, ne na disku u projektu, kde jsme editovali .classpath) a v něm je nyní v mém případě 11 jar knihoven.</p> <p>Pokud se stále Maven Dependencies neobjeví, zkuste re-savnout soubor pom.xml, což je i do budoucna dobrá cesta, jak donutit Maven plugin, aby provedl update závislostí.</p> <p>Ještě si zkontrolujte, že máte zaškrtnutý checkbox automatického buildování – v menu Eclipse Project/Build Automatically. Můžete také zkusit udělat Project/Clean…/Cle­an all project.</p> <h3>Lokální maven repository</h3> <p>Všechny jar knihovny, které jsou v kontejneru Maven Dependencies, maven stáhl k vám na lokální disk do tzv. lokálního maven repositáře. Cestu lze vidět v Eclipse u každé jar knihovny. Je to závislé na používaném OS, např. ve Windows 7 je cesta k repositáři tato:</p> <p><strong>C:\Users\&lt;VASE_JME­NO&gt;\.m2\reposi­tory…</strong></p> <p>Pro naše potřeby není znalost tohoto umístění příliš důležitá, ale není špatné o tom vědět.</p> <h3>Závěr</h3> <p>Ačkoliv jsem minule sliboval již Hello world, tak nakonec se ukázala problematika rozjetí maven pluginu pro Eclipse širší, než jsem původně čekal :-) a určitě si zasloužila samostatný článek . Náš projekt je nyní připraven používat Struts2 a přidávání dalších závislostí je již analogické, pouze přidáme dependency do pom.xml. Příště začneme rovnou rozjetím Tomcatu v Eclipse (což je oproti maven opravdu hračka) a konečně vypsáním Hello world v prohlížeči za pomocí frameworku Struts2.</p> http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-maven-plugin-pro-eclipse-a-pridani-struts2-do-projektu-2-dil Webová aplikace v Javě od A do Z – Eclipse: příprava prostředí a založení projektu (1. díl) Wed, 07 Nov 2012 12:11:40 GMT http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-eclipse-priprava-prostredi-a-zalozeni-projektu-1-dil <p>Eclipse je profesionální vývojové prostředí, které vzniklo proto, aby programátoři nemuseli vyvíjet své aplikace v poznámkovém bloku nebo PSPadu :-) Přináší s sebou značný komfort pro vývoj, ale také vyšší nároky na hardware počítače…</p> <h3>Eclipse</h3> <p>Eclipse je profesionální vývojové prostředí, které vzniklo proto, aby programátoři nemuseli vyvíjet své aplikace v poznámkovém bloku nebo PSPadu :-) Přináší s sebou značný komfort pro vývoj, ale také vyšší nároky na hardware počítače a občas klade nároky na trpělivost uživatele – podobně jako u Windows je třeba jej čas od času restartovat nebo přeinstalovat. Alternativou jsou např. Netbeans, ale nebudu se zde pouštět do polemik, co je lepší, těch najdete na internetu dost. Já pracuji většinu své programátorské kariéry v Eclipse a jsem s nimi docela spokojený, takže v seriálu budu používat toto vývojové prostředí.</p> <p>Eclipse stáhnete na adrese <a href="http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a>, stáhněte verzi <strong>Eclipse IDE for Java EE Developers</strong> Používám Windows7, takže stahuji 64 bitovou verzi, ale neměl by snad být pro potřeby našeho seriálu rozdíl mezi touto a 32 bitovou verzí. Po stáhnutí Eclipse si jej rozbalte do libovolné složky a spusťte jej. Další návod píši pro tuto verzi:</p> <p>Eclipse Java EE IDE for Web Developers.</p> <p>Version: Juno Service Release 1, Build id: 20120920–0800</p> <p>Je samozřejmé, že se Eclipse vyvíjí, proto mohou být některé věci v jiných verzích Eclipse trošku jinak nebo jinde. Nicméně mohu říct, že za posledních 6 let (od roku 2006 co v Eclipse vyvíjím) se těch základních věcí, kterým se budu věnovat, mnoho nezměnilo, takže doufám, že v seriálu popsané konfigurace Eclipse nepřijdou časem o aktuálnost.</p> <p>Nejsem nějaký Eclipse guru, takže následující jednoduchý průvodce je pouze popis víceméně nejjednoduššího postupu, jak začít programovat v tomto vývojovém prostředí.</p> <h3>Spuštění, základní nastavení a konfigurace Eclipse</h3> <p>Po startu po vás bude Eclipse chtít cestu k workspace, což je místo, kam si bude ukládat svoje nejrůznější konfigurační soubory týkající se vaší pracovní plochy. Zvolte libovolnou cestu, já jsem zvolil C:\Users\Luke\Wor­kspace\Nullpo­inter. Do této složky se nebudou ukládat přímo soubory projektu, pokud to explicitně nenastavíte (viz dále). Poté uvidíte nejspíš nějakou uvítací obrazovku, v pravém horním rohu se zpravidla nachází odkaz Workbench (aspoň pár verzí už je to stejné), na který klikněte, což vás pošle již přímo do prostředí, kde můžete začít vyvíjet.</p> <p><strong>Nastavení vzhledu workbench</strong> Nastavení vzhledu je hodně individuální, asi by se dalo říci, že co programátor, to jiné preference vzhledu. Já zde popíšu způsob, jak si prostředí nastavuji já. Nikomu samozřejmě toto rozvržení nenutím, ale pro případné nováčky v Eclipse to určitě není špatný způsob jak začít. Nic zásadního zde totiž nechybí a jsou zde zobrazeny jen nejnutnější prvky.</p> <p>Pokud jste již zvyklí nějak s Eclipsem pracovat, klidně následující číslované kroky přeskočte:</p> <ol> <li>Já jsem zvyklý pracovat v <strong>perspektivě Java</strong>, perspektiva se přepíná v pravém horním rohu. Defaultně tam bude nastavená perspektiva Java EE.</li> <li>V pravém sloupečku vypnu vše, co tam je standardně zobrazené (např. okno Outline či Task list). Zvětší se tak plocha pro samotné programování.</li> <li>V dolní okně ponechám záložku <strong>Problems</strong>, odstraním záložku Java doc a Declaration. Dále sem přidám 2 užitečné záložky, <strong>Console</strong> a <strong>Server</strong>. Ty přidáte prostřednictvím menu Eclipse – Window/Show view/Console a Window/Show view/Other/Ser­ver/Servers.</li> <li>Výsledek je tedy následující: v levém sloupci ponechaný <strong>Package explorer</strong>, napravo zatím prázdné okno, kde se bude psát kód a ve spodní části obrazovky pruh se záložkami Problems, Console a Servers. Zde se pak budou automaticky objevovat některé další záložky, např. Search pro výsledky hledání apod.</li> </ol> <h3>Základní konfigurace Eclipse workspace</h3> <p>Nejdůležitější je správně nastavit Javu, kterou budeme v našem workspace používat. Pokud ji nemáte stáhnutou, tak ji stáhněte ze stránek <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">http://www.oracle.com/…s/index.html</a> a nainstalujte. <strong>V dalších částech seriálu budeme pracovat s JDK</strong> (nikoliv s JRE), proto nainstalujte nejnovější JDK, které v seznamu najdete. V době psaní tohoto článku (listopad 2012) stahuji verzi 7, devátý update, 64 bitová verze. Instalátor vám pak ukáže, kam Javu bude instalovat (standardně C:\Program Files\Java\jdk…). Tuto cestu si zapamatujte, v Eclipse ji pak bude chtít. Pokud máte nyní spuštěný Eclipse, nejspíš budete vyzváni instalátorem, abyste jej zavřeli.</p> <p><strong>Po úspěšné instalaci Javy Eclipsům řekneme, že budeme používat JDK</strong>, které jsme právě stáhli. To se dělá ve Window/Preferen­ces/Java/Insta­lled JREs. Zde klikněte na tlačítko Add, zvolte Standard VM a do JRE Home nastavte cestu, kam jste nainstalovali JDK – u mě to bylo C:\Program Files\Java\jdk1­.7.0_09. Pak dejte Finish a** v seznamu Installed JRE přepněte checkbox na JDK** a dejte ok.</p> <p>Dále se ještě hodí změnit <strong>kódování ve workspace</strong> na UTF-8 nebo na nějaké jiné, které budete chtít používat. To se dělá ve Window/Preferences, do vyhledávacího rámečku napište <strong>encoding</strong> a to vám vyfiltruje složky General, Web a XML. Nejdůležitější je General/Workspace, dolů do rámečku Text file encoding dejte Other/požadované kódování. Pokud chcete, můžete změnit kódování i u jiných souborů, jak ponechávám defaultní nastavení.</p> <p>Další věcí, které se ještě hodí zkraje nastavit, je <strong>formatter.</strong> Eclipse vám automaticky formátuje váš java kód, přidává např. prázdné řádky, má nastavenou nějakou velikost TABu, délku řádku po které vám automaticky zalomí text atd. Formatter najdeme ve Window/Preferences a do vyhledávacího okna napíšeme <strong>formatter</strong>. Zajímá nás nyní především <strong>Java/Code style/Formatter</strong>, kde je nastavený jako Active profile profil <strong>Eclipse [built-in]</strong>. Stiskneme tlačítko New a nový profil nazveme např. podle názvu naší firmy, projektu nebo jak chceme. Náš nový profil podědí nastavení Eclipse [built-in] profile, takže můžeme provést jen nějaké změny, dle naší libosti. Já většinou nastavuji hned na první záložce Indentation Tab policy na Space only a Tab size a Indentation size nastavím na 2, ale jako většina textu v této kapitole, je to individuální a mým cílem je především ukázat místa užitečných počátečních konfigurací Eclipse workspace. Dále se hodí záložka Line wrapping, na které si můžete nastavit především Maximum line width, které je defaultně 80. V dnešní době širokoúhlých monitorů je škoda tam nenastavit o něco víc, třeba 120 nebo 140, ale opět záleží na tom, co preferujete. Já třeba nemám rád, když mi nějaký delší příkaz ujede na druhý řádek, klidně si i horizontálně zascroluji, protože pak vždy vím, že na začátku řádku mám i začátek nového příkazu. Vámi nastavený formatter můžete i pomocí tlačítka Export All… vyexportovat do xml souboru a někdo jiný, či někdy v budoucnu i vy sami si můžete individuálně nastavený formatter pomocí tlačítka Import… načíst. To se hodí především ve firmách, kde více vývojářů pracuje na jednom projektu a je nežádoucí, aby měl každý jinak nastavený formatter především proto, že každý pak commituje jinak naformátované soubory a velmi špatně se hledají vlastní změny, které programátor v souboru udělal. V Eclipse můžete kdykoliv použít klávesovou zkratku CTRL+SHIFT+F, který vám právě otevřený soubor (v současnosti ještě žádný nemáme) naformátuje dle zvoleného formatteru.</p> <h3>Užitečné klávesové zkratky v Eclipse</h3> <p>Následuje seznam nejpoužívanějších a velmi užitečných klávesových zkratek v Eclipse. Pokud jste v Eclipsech a v Javě ještě moc nedělali, tak vám to asi mnoho neřekne, nicméně se sem můžete kdykoliv později vrátit a na zkratky se podívat. Především až již budeme mít založený nový projekt a uložených pár java a jsp souborů, si budete moci přímo vyzkoušet, co jaká zkratka dělá.</p> <p><strong>CTRL + SHIFT + R:</strong> hledání souborů</p> <p><strong>CTRL + SHIFT + T:</strong> hledání Java tříd (podmnožina vrchního dotazu)</p> <p><strong>CTRL + O:</strong> hledání metod v rámci Java třídy</p> <p><strong>CTRL + Mezerník:</strong> kontextová nápověda Eclipsu</p> <p><strong>CTRL + Click:</strong> pátrání po původu např. CTRL+ Click na proměnnou přenese na místo, kde je definovaná</p> <p><strong>CTRL + T:</strong> u když se použije při označení interface metody, ukáže implementaci této metody</p> <p><strong>CTRL + SHIFT + F:</strong> zapne automatické formátování u java tříd</p> <p><strong>CTRL + SHIFT + O:</strong> organizuje importy – automaticky vygeneruje všechny nutné importy, které</p> <p>třída potřebuje a odstraní importy nepoužívané</p> <p><strong>CTRL + M:</strong> zobrazí přes celou obrazovku okno, na kterém je focus (hodí se zejména u okna, do kterého píšeme kód</p> <h3>Založení webového projektu v Eclipse</h3> <p>Nyní již přišel čas založit konečně nový webový projekt. Ten založíme v Eclipse pomocí menu <strong>File/New…/Other­../Web/Dynamic web project</strong>. V následujícím okně vybereme především <strong>Project name</strong> a <strong>Project location</strong>, což je místo na pevném disku, kde budeme mít uloženy soubory projektu (všechny java, jsp, xml apod.). Je třeba rozlišovat mezi cestou k workspace (viz výše) a Project location, což se alespoň mě v začátcích trošku pletlo. V prvním případě se jedná o uložiště konfiguračních souborů nastavení workspace, které jsme dělali před chvílí (viz výše) a v druhém případě jsou to soubory s naším java a html kódem. Někdo obojí cpe do jednoho adresáře, já to mám radši oddělené, takže je to zase na vás, zda si Project location nastavíte nebo jestli ponecháte defaultní. Každopádně si cestu zapamatujte, ať víte, kde se nachází vaše projektové soubory (ne že by to nešlo později zjistit). Když zvolíte Next, budete dotázání na specifikaci zdrojových složek (source folder). Doporučuji smazat src, které tam defaultně je a zadat tyto tři složky:</p> <p><strong>src/main/java</strong> – zde budeme mít všechny java soubory</p> <p><strong>src/main/resou­rces</strong> – zde budeme mít různé konfigurační soubory pro frameworky, soubor s texty pro naše stránky atd. viz další díly seriálu</p> <p><strong>src/test/java</strong> – zde budeme mít testovací java třídy, hlavně JUnit testy (viz pozdější díly našeho seriálu)</p> <p>Stiskneme tlačítko Next a na poslední obrazovce wizardu zaškrtneme checkbox <strong>Generate web.xml deployment descriptor.</strong> Po stisknutí tlačítko Finish bude chtít Eclipse otevřít Java EE perspektivu. Jak jsem již psal výše, je to individuální, v jaké perspektivě se rozhodnete pracovat, ale já budu v dalších částech seriálu pracovat v Java perspektivě.</p> <h3>Nastavení Javy JDK do vytvořeného webového projektu</h3> <p>Nyní je důležité nastavit projektu, aby používal JDK, které jsme již nastavili výše. Nyní v projektu vidíte (mimo dalších složek, např. námi nastavených systémových) také Javu JRE System Library [JavaSE-1.6]. Klikneme na tento kontejner pravým tlačítkem myši a zvolíme v kontextovém menu nabídku <strong>Properties.</strong> Zde vybereme možnost <strong>Workspace default JRE (jdk…). Tohle je důležitý krok, protože jinak bychom používali špatnou javu, což by vedlo k nejrůznějším problémům při pozdějších konfiguracích a samotnému běhu aplikace.</strong></p> <h3>Závěr</h3> <p>Nyní máme založený nový webový projekt ve vývojovém prostředí Eclipse, u kterého jsme se seznámili s jeho základním nastavením. V další části seriálu se budeme věnovat především stáhnutí maven pluginu do Eclipse a načtení potřebných frameworků Struts2, Spring a Hibernate a dalších užitečných knihoven pomocí MAVENu do našeho projektu. Dále si již zkusíme spustit náš projekt na serveru Tomcat uvnitř Eclipse a vypsat naší aplikací do webového prohlížeče nic menšího než „Hello World“. :-)</p> http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-eclipse-priprava-prostredi-a-zalozeni-projektu-1-dil Webová aplikace v Javě od A do Z – Úvod (NULLtý díl) Thu, 25 Oct 2012 21:30:08 GMT http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-uvod-nullty-dil <p>V tomto seriálu si ukážeme, jak rozchodit webový systém naprosto od nuly, za použití těchto technologií: Java, Maven, Spring, Struts2, Hibernate, Oracle (nebo MySQL) a JQuery ve vývojovém prostředí Eclipse a serveru Tomcat. Od tohoto seriálu můžete očekávat detailní a srozumitelný návod, jak začít vývoj webové aplikace u vás na lokálním počítači. Výsledkem bude fungující webový systém postavený na MVC architektuře, který bude demonstrovat základní použití všech zmíněných technologií.</p> <h3>Důvody vzniku tohoto seriálu</h3> <p>Start-up jakéhokoliv projektu je náročnější, než by se mohlo zdát a nikdo vás za to většinou neocení. Spíš se dočkáte vět typu: „A to jste jeden formulář dělali dva týdny?“ nebo: „Chcete mi říct, že jsem zaplatil týden vývoje za to, že aplikace umí vypsat větu Hello world!???“ nebo si sami frustrovaně řeknete něco jako: „Ach jo, už se s tím týden drbu a pořád mi to vyhazuje nějaké výjímky, které nejdou odstranit ani podle všech možných návodů na internetu. Já už bych chtěl konečně začít psát vlastní aplikaci.“</p> <p>Počáteční konfigurací projektu a napsání základních obecných funkcí je práce, kterou neděláte každý den, takže se snadno zapomínají i věci, které jste si pamatovali a to vůbec nemluvím o věcech, které jste ani nikdy nevěděli :-) Samotnému se mi stalo, když jsem měnil práci, že jsem odešel z projektu, který měl za sebou mnoho let vývoje a slušné vývojářské zázemí a měl jsem najednou začít vyvíjet projekt zcela nový, takříkajíc od píky. Nemusí to ale být jen zmíněná změna práce, chcete si například rozjet nějaký soukromý projekt doma. V těchto případech zjistíte, kolik věcí již berete jako samozřejmost a to nemluvím jen o konfiguracích Springu, Hibernatu apod. Muvím i o značném počtu nezbytných utilitních funkcí a objektů, které jste si zvykli používat téměř jako vestavěné funkce jazyka Java popř. Javascriptu a najdenou se divíte, co to s tím Eclipsem zase je, že vám tyto metody nenabízí v kontextové nápovědě :-)</p> <p>Tento seriál má pomoci výrazně zrychlit tuto, dovolím si říct, neradostnou a nudnou část vývoje a mimo to také poskytnout návod na použití zmiňovaných technologií v podobě komplexního praktického příkladu.</p> <p><strong>Systém, který vznikne jako výsledný produkt tohoto seriálu, bude umět:</strong></p> <ul> <li>Registrovat nového uživatele za pomocí obsáhlejšího registračního formuláře včetně klient-side a server-side validací</li> <li>Vypsat seznam uživatelů v pěkné tabulce umožňující rychlé řazení a filtrování dle nejrůznějších hledisek</li> <li>Přihlásit uživatele do systému, provedení základní autentizace a autorizace a rozlišit 3 typy oprávnění – anonymní uživatel, registrovaný uživatel, admin a super admin.</li> <li>Možnost editace a mazání existujících uživatelů adminem + možnost přiřazení administrátor­ského práva</li> <li>Správa požadavků AJAXem</li> </ul> <p><strong>To bude obnášet z vývojářského hlediska především:</strong></p> <ul> <li>Systém bude postaven na MVC architektuře</li> <li>Aplikace se bude pomocí Mavenu buildovat přímo v Eclipse a umožní ji spustit ve webovém prohlížeči</li> <li>Rozjetí databáze</li> <li>CRUD (Create, Read, Update, Delete, tj čtení) v rámci celé MVC architektury</li> </ul> <p><strong>To obnáší zvládnout jednotlivé dílčí kroky, které zde nyní vyjmenuji. Předpokládám, že se budou víceméně krýt obsahově i chronologicky s jednotlivými díly tohoto seriálu:</strong></p> <ol> <li>Stáhnutí a konfigurace vývojového prostředí Eclipse, založení nového projektu, download potřebných pluginů (maven plugin).</li> <li>Download externích knihoven Spring, Hibernate a Struts2 a jejich integrace do našeho systému.</li> <li>Konfigurace Spring a Struts2 a „Hello World!“.</li> <li>Konfigurace Spring a Hibernate a „Hello World!“ v kompletní MVC architektuře.</li> <li>Vytvoření DB tabulky Uživatelé a CRUD nad touto tabulkou za pomocí základního webového formuláře – tzn. vytvoření, výpis, aktualizace a smazání uživatele.</li> <li>Přidání dalších DB tabulek pro komplexnější ukládání informací o uživateli a tedy i správná konfigurace Hibernatu pro DB vazby typu 1:n a m:n.</li> <li>Vytvoření moderního formuláře (klient-side validace, vyhledávací comboboxy, ajaxové odesílání formuláře apod.) pomocí JQuery a jeho pluginů.</li> <li>Vytvoření moderní tabulky (především inteligentní řazení a filtrování) pomocí JQuery a jeho pluginů.</li> <li>Přihlášení uživatele pomocí Struts2 interceptoru a jeho autorizace a autentizace.</li> <li>Základní testování pomocí JUnit testů a automatické webové testování Selenium.</li> </ol> <p>První díl seriálu se plánuji na začátek listopadu 2012.</p> http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-uvod-nullty-dil JQuery Datatables columnFilter plugin: problém s více tabulkami na jedné stránce Tue, 23 Oct 2012 20:21:34 GMT http://www.nullpointer.cz/jquery-datatables-columnfilter-plugin-problem-s-vice-tabulkami-na-jedne-strance <p>Column filtr plugin pro jquery plugin DataTables zlobí, když se na jedné stránce vyskytnou dvě nebo více tabulek (typu datatable). Sloupcový filtr pak chybně filtruje pouze poslední definovanou tabulku. V praxi to vypadá tak, že když se pokusíte použít sloupcový filtr např. první tabulky, filtruje se úplně jiná tabulka – ta poslední…</p> <h3>Problém</h3> <p>Column filtr (dále „sloupcový filtr“) plugin (<a href="http://code.google.com/p/jquery-datatables-column-filter/">http://code.google.com/…lumn-filter/</a>) pro jquery plugin DataTables (<a href="http://datatables.net/">http://datatables.net/</a>) zlobí, když se na jedné stránce vyskytnou dvě nebo více tabulek (typu datatable). Sloupcový filtr pak chybně filtruje pouze poslední definovanou tabulku. V praxi to vypadá tak, že když se pokusíte použít sloupcový filtr např. první tabulky, filtruje se úplně jiná tabulka – ta poslední.</p> <h3>Upozornění</h3> <p><strong>Používám colum jquery.dataTa­bles.columnFil­ter.js verzi 0.9</strong>, která je jediná ke stažení na oficiálních stránkách zde – <a href="http://code.google.com/p/jquery-datatables-column-filter/downloads/list">http://code.google.com/…wnloads/list</a> (v době psaní tohoto článku). Sice lze najít v svn trunku vyšší verzi (<a href="http://jquery-datatables-column-filter.googlecode.com/svn/trunk/media/js/jquery.dataTables.columnFilter.js">http://jquery-datatables-column-filter.googlecode.com/…umnFilter.js</a>), v době psaní tohoto článku konkrétně 1.5, ale ta mi narozdíl od verze 0.9 nefunguje (a nevím proč), takže nemohu vyzkoušet, jestli je tam stejný problém.</p> <h3>Řešení</h3> <p><strong>Řešení bude modifikovat soubor jquery.dataTa­bles.columnFil­ter.js</strong>, pokud tedy používáte jinou verzi než 0.9, je možné, že se jednotlivé řádky mohou více či méně lišit, ale oprava problému je principiálně jednoduchá, takže věřím, že řešení bude použitelné i v jiných verzích.</p> <p>Naprosto stejný problém se řeší i zde: <a href="http://datatables.net/forums/discussion/10238/multiple-tables-in-the-same-page/p1">http://datatables.net/…same-page/p1</a> a je tam moje odpověď, jak vyřešit tento problém drobnou modifikací zdrojového souboru <strong>jquery.dataTa­bles.columnFil­ter.js</strong>. Následující řádky jsou volným přepisem této mé odpovědi do češtiny:</p> <p><strong>Veškerý níže zmiňovaný kód se týká souboru jquery.dataTa­bles.columnFil­ter.js</strong>. Problém začíná na tomto řádku:</p> <pre class="cpp"><code>$.fn.columnFilter = function (options) { oTable = this;</code></pre> <p>Globální proměnná oTable nabude hodnoty poslední tabulky, kterou definujeme. Funkce fnCreateInput se stará o vytváření input elementu používaného pro textové filtrování (ostatní typy filtrovaných polí jako date-range, number-range jsou víceméně analogické) a má tento předpis:</p> <pre class="cpp"><code>function fnCreateInput(regex, smart, bIsNumber) {</code></pre> <p>uvnitř je tento kód:</p> <pre class="cpp"><code>if (bIsNumber &amp;&amp; !oTable.fnSettings().oFeatures.bServerSide) { input.keyup(function () { /* Filter on the column all numbers that starts with the entered value */ oTable.fnFilter('^' + this.value, index, true, false); }); } else { input.keyup(function () { /* Filter on the column (the index) of this element */ oTable.fnFilter(this.value, index, regex, smart); }); }</code></pre> <p>input.keyup se zavolá, když uživatel začne psát do filtr inputu a spustí se filtrování. <strong>Problém je proměnná oTable, která má nyní hodnotu poslední definované tabulky. Jednoduché řešení spočívá ve změně proměnné oTable z globální na lokální:</strong></p> <pre class="cpp"><code>function fnCreateInput(regex, smart, bIsNumber, oTable) {</code></pre> <p>Totéž musíte udělat i pro další funkce, které generují jiné typy sloupcového filtrování:</p> <pre class="cpp"><code>function fnCreateInput(regex, smart, bIsNumber, oTable) function fnCreateRangeInput(oTable) function fnCreateDateRangeInput(oTable) function fnCreateSelect(aData, oTable)</code></pre> <p>A nakonec je samozřejmě třeba předat těmto funkcím správný argument oTable v místě, kde se volají. K tomu dochází v této funkci:</p> <pre class="cpp"><code>$.fn.columnFilter = function (options) {</code></pre> <p>Zde najdete příkaz switch, kde najdete postupně volání všech zmiňovaných funkcí a předáte tam argument oTable, který má zde ještě správnou hodnotu (je tam aktuálně vytvářená tabulka):</p> <pre class="cpp"><code>switch (aoColumn.type) { case "number": fnCreateInput(true, false, true, oTable); break; case "text": bRegex = (aoColumn.bRegex == null ? false : aoColumn.bRegex); bSmart = (aoColumn.bSmart == null ? false : aoColumn.bSmart); fnCreateInput(bRegex, bSmart, false, oTable); break; case "select": fnCreateSelect(aoColumn.values, oTable); break; case "number-range": fnCreateRangeInput(oTable); break; case "date-range": fnCreateDateRangeInput(oTable); break; default: break;</code></pre> <p>A to je vše. Můžete si stáhnout celý <a href="upload/jquery.datatables.columnfilter.js">modifkovaný columnFilter plu­gin</a></p> <h3>Závěr</h3> <p>Nejedná se rozhodně o univerzální řešení, ani nijak zvlášť hezké (jsme nuceni modifikovat knihovnu třetí strany), ale je funkční. Je možné, že jde skutečně o bug v této jinak dobré knihovně a nevím, zda je již vyřešen (špatně mi funguje dnes aktuální verze 1.5) nebo se v budoucnu vyřeší. Každopádně výše zmíněný postup vám může pomoci v případě stejného problému rychle rozběhat více tabulek datatables s column filtrem na jedné stránce a nemusíte nad tím strávit celý den jako já :-)</p> http://www.nullpointer.cz/jquery-datatables-columnfilter-plugin-problem-s-vice-tabulkami-na-jedne-strance Zobrazování exceptions v ajaxových requestech pomocí Struts2 a JQuery Mon, 08 Oct 2012 20:51:04 GMT http://www.nullpointer.cz/zobrazovani-exceptions-v-ajaxovych-requestech-pomoci-struts2-a-jquery <p>Obecně se dá říci, že se v aplikaci při ajaxových requestech setkáme se třemi různými typy výjímek:</p> <ol> <li>Neočekávaná výjímka při ajaxovém načítání nějakého obsahu, např. pomocí JQuery metody load()</li> <li>Neočekávaná výjímka při ajaxovém requestu, který nenačítá žádný obsah…</li> </ol> <p>Obecně se dá říci, že se v aplikaci při ajaxových requestech setkáme se třemi různými typy výjímek:</p> <ol> <li>Neočekávaná výjímka při ajaxovém načítání nějakého obsahu, např. pomocí JQuery metody load()</li> <li>Neočekávaná výjímka při ajaxovém requestu, který nenačítá žádný obsah, ale pouze volá nějaké vzdálené metody na serveru, typicky ajaxový submit formuláře nebo obecně ajaxové volání nějaké metody, která má za úkol provést update databáze</li> <li>Očekávaná výjímka, pomocí které uživatele informujeme, že z nějakého důvodu nemůže provést operaci – např. submit formuláře v případě, že nejsou vyplněné všechny povinné položky (za předpokladu, že není nebo nefunguje validace na straně klienta)</li> </ol> <p><strong>Zásadní rozdíl mezi očekávanými a neočekávanými výjímkami je ten, že v případě neočekávaných chceme vypsat kompletní výjímku včetně stacktrace (abychom rychle viděli, o jakou jde výjímku a kde v kódu nastala), kdežto u očekávaných výjímek budeme chtít pouze zobrazit chybovou hlášku uživateli (např. „Nevyplnili jste všechna povinná pole“).</strong> Určitě není žádoucí, aby se u očekávaných výjímek vypisoval celý stacktrace.</p> <h3>Řešení:</h3> <p>Ve Struts2 namapujeme obecnou exception na nějakou naši metodu, ve které chybu vypíšeme do konzole a uložíme ji např. do session včetně kompletního stacktrace, abychom k ní později mohli přistoupit (bude ukázáno dále).</p> <p><strong>Struts2 – struts.xml</strong></p> <pre class="xml"><code>&lt;global-exception-mappings&gt; &lt;exception-mapping result="error" exception="java.lang.Exception"&gt;&lt;/exception-mapping&gt; &lt;/global-exception-mappings&gt; &lt;global-results&gt; &lt;result name="error" type="chain"&gt; &lt;param name="actionName"&gt;exceptionHandle&lt;/param&gt; &lt;/result&gt; &lt;/global-results&gt; &lt;action name="exceptionHandle" method="exceptionHandle" class="cz.nullpointer.actions.MyExceptionHandleAction"&gt; &lt;result name="error"&gt;/myErrorPage.jsp&lt;/result&gt; &lt;result name="ajaxError" type="httpheader"&gt;500&lt;/result&gt; &lt;/action&gt; &lt;action name="exceptionContent" method="exceptionContent" class=" cz.nullpointer.actions.MyExceptionHandleAction "&gt; &lt;result name="success"&gt;/myErrorPage.jsp&lt;/result&gt; &lt;/action&gt;</code></pre> <p>V příkladu se budou všechny výjímky mapovat na akci exceptionHandle, kterou spravuje třída cz.nullpointer­.actions.MyEx­ceptionHandle­Action, konkrétně metoda exceptionHandle. Akci exceptionContent a resulty akce exceptionHandle „error“ a „ajaxError“ si vysvětlíme dále.</p> <p>V metodě exceptionHandle budeme muset rozlišovat, **zda chyba vznikla během ajaxového požadavku, který nevrací žádný obsah (např. submit formuláře) nebo během ajaxového či „obyčejného“ requestu, který obsah (stránku) vrací. Z tohoto důvodu budeme do našich ajaxových requestů přidávat nějaký parametr, např „&amp;noContentAjax­Call=true“. ** V prvním případě totiž potřebujeme vrátit chybový http status (např. 500), aby ajaxová funkce poznala, že je něco v nepořádku, a že se bude vypisovat výjímka (viz dále).</p> <p>V případě requestu vracejícího obsah budeme vracet chybovou stránku a výjímka se tak zobrazí místo obsahu, který jsme chtěli původně načíst (a http status bude v tomto případě 200). Dále zde budeme rozlišovat, o jaký typ výjímky se jedná, jestli o neočekávanou (tedy všechny výjímky kromě očekávaných) nebo očekávánou. V příkladu všechny očekávané výjímky sloučíme do jedné runtime výjímky OcekavanaVyjim­kaException.</p> <p><strong>Java – OcekavanaVyjim­kaException</strong></p> <pre class="java"><code>public class OcekavanaVyjimkaException extends RuntimeException { private static final long serialVersionUID = 1L; public OcekavanaVyjimkaException (String message) { super(message); } }</code></pre> <p>Budeme předpokládat, že všechny očekávané výjímky v aplikaci budou vytvářet instanci exception OcekavanaVyjim­kaException, např. takto:</p> <pre class="java"><code>throw new OcekavanaVyjimkaException(“Nebyla vyplněna všechny povinná pole formuláře!”);</code></pre> <p>Java třída MyExceptionHan­dleAction pak může vypadat následovně:</p> <p><strong>Java – MyExceptionHan­dleAction</strong></p> <pre class="java"><code>public class MyExceptionHandleAction extends ActionSupport { boolean noContentAjaxCall; public String exceptionHandle() { ActionContext ac = ActionContext.getContext(); String exceptionStack = ac.getValueStack().findValue("exceptionStack").toString(); String exception = ac.getValueStack().findValue("exception").toString(); System.out.println(exceptionStack); //Vypis do konzole setExceptionCustom(exception); //Ulozeni do session, setter viz nize //Zde může být další log vyjímek např. do DB nebo do textového souboru if (!exception.contains(OcekavanaVyjimkaException.class.getName())) { setExceptionStackCustom(exceptionStack); //Ulozeni do session, setter viz nize } if (isNoContentAjaxCall ()) { return "ajaxError"; // httpheader=500 } else { return ERROR; // myErrorPage.jsp a httpheader=200 } } public String exceptionContent() { return SUCCESS; } public boolean isNoContentAjaxCall () { return noContentAjaxCall; } public void setNoContentAjaxCall (boolean noContentAjaxCall) { this. noContentAjaxCall = noContentAjaxCall; } public Map getSession() { return ActionContext.getContext().getSession(); } public void setExceptionStackCustom(String exceptionStackCustom) { getSession().put("exceptionStackCustom", exceptionStackCustom); } public String getExceptionStackCustom() { String result = (String) getSession().get("exceptionStackCustom"); getSession().put("exceptionStackCustom", null); return result ; } public void setExceptionCustom(String exceptionCustom) { getSession().put("exceptionCustom", exceptionCustom); } public String getExceptionCustom() { String result = (String) getSession().get("exceptionCustom"); getSession().put("exceptionCustom", null); return result ; } public String getExceptionCustomOnlyMessage(String exceptionText) { return exceptionText.replace(OcekavanaVyjimkaException.class.getCanonicalName(), "").substring(2); getSession().put("exceptionCustom", null); //oseknutí OcekavanaVyjimkaException }</code></pre> <p>Všimněte si, že v metodě exceptionHandle() uložíme stacktrace chyby do session pouze v případě, že se nejedná o instanci exception OcekavanaVyjim­kaException.</p> <p>Čtení ze session je destruktivní, tzn. po první přečtení výjímky uložené v session dojde ke smazání, aby to v session zbytečně „neviselo“, když jsme již text chyby přečetli a zobrazili</p> <p>Dále si všimňete, že na základě booleanovského parametru noContentAjaxCall se vrací result „ajaxError“ pro requesty nevracející obsah nebo „error“ pro requesty vracející obsah – mapování viz. výše uvedený struts.xml. Poslední komentář zaslouží metoda getExceptionCus­tomOnlyMessage(String exceptionText), která vrátí ze standardního exception pouze zprávu, tedy např. po</p> <pre class="java"><code>throw new OcekavanaVyjimkaException(“Nebyla vyplněna všechny povinná pole formuláře!”);</code></pre> <p>nevrátí metoda „OcekavanaVyjim­kaException: Nebyla vyplněna všechny povinná pole formuláře!„, ale pouze „Nebyla vyplněna všechny povinná pole formuláře!„ Tato metoda se volá s JSP, jak bude ukázáno v následujícím odstavci.</p> <p>A nyní JSP myErrorPage.jsp (viz struts.xml), které se hned vrátí při ajax requestu vracejícímu obsah (noContentAjaxCall = false) nebo se teprve bude volat pro ajaxové requesty nevracející obsah (noContentAjaxCall = true) – viz dále.</p> <p><strong>JSP – myErrorPage.jsp</strong></p> <pre class="html"><code>&lt;s:if test=" noContentAjaxCall "&gt; &lt;s:set var="exception" value="%{exceptionCustom}"&gt;&lt;/s:set&gt; &lt;s:set var="exceptionStack" value="%{exceptionStackCustom}"&gt;&lt;/s:set&gt; &lt;/s:if&gt; &lt;s:else&gt; &lt;s:set var="exception" value="%{exception}"&gt;&lt;/s:set&gt; &lt;s:set var="exceptionStack" value="%{exceptionStack}"&gt;&lt;/s:set&gt; &lt;/s:else&gt; &lt;s:if test="#exceptionStack == null || #exceptionStack == ''"&gt; &lt;s:property value="getExceptionCustomOnlyMessage(#exception)"/&gt; &lt;/s:if&gt; &lt;s:else&gt; &lt;div class="error"&gt; &lt;s:property value="#exception" /&gt; &lt;/div&gt; &lt;div class="errorStack"&gt; &lt;s:property value="#exceptionStack" /&gt; &lt;/div&gt; &lt;/s:else&gt;</code></pre> <p>V JSP vidíme, že podle prázdné či neprázdné proměnné exceptionStack se vypíše buď jen text exception nebo kompletní exception včetně stacktrace.</p> <p><strong>Ukázky použití.</strong> V případě metody load() načítající obsah např. do DIVu „#ajaxObsahDiv“ se nemusíme o nic starat:</p> <pre class="cpp"><code>$("#ajaxObsahDiv").load("/actionWhichThrowsException") ;</code></pre> <p><strong>V případě chyby se vrátila rovnou chybová stránka (viz výše), která se zobrazí v DIVu „#ajaxObsahDiv“</strong><br /> V případě ajaxového requestu, který má za úkol např. pouze updatnout data v DB se již trošku starat musíme a chybovou stránku musíme zavolat ajaxově v error callbacku.</p> <pre class="cpp"><code>$.get(“/actionWhichThrowsException”, function(result) { }).error(function(e) { showErrorAjaxDialog(); });</code></pre> <p><strong>Nyní zbývá definovat JQuery metodu použitou showErrorAjax­Dialog().</strong></p> <p>Pro zobrazení chyby za neobsahového ajax requestu využijeme komponentu z JQuery UI – dialog. Současné řešení předpokládá, že máme někde na stránce prázdný div ve tvaru:</p> <pre class="html"><code>&lt;div id=”ajaxExceptionDialog”&gt;&lt;/div&gt;</code></pre> <p>do kterého budeme načítat JQuery dialog. Pak můžeme v JQuery definovat metodu showErrorAjax­Dialog(), kterou budou volat ajaxové metody v případě chyby.</p> <p><strong>JQuery:</strong></p> <pre class="cpp"><code>function showErrorAjaxDialog () { $("#ajaxExceptionDialog").load("exceptionContent.action?ajaxCall=true").dialog({ "width":"500px" }); }</code></pre> <p><strong>Tento ajax volá struts2 akci exceptionContent defnovanou výše“. Výsledkem je samozřejmě opět chybová stránka, která se tentokrát zobrazí v dialogu.</strong></p> <h3>Závěr:</h3> <p>Toto řešení ukazuje především způsob práce s vyjímkami ve Struts2 a jejich distrubici do výsledku ajaxových requestů volaných pomocí JQuery. Řešení je samozřejmě využitelné i pro ostatní JQuery metody využívající ajax, včetně nejrůznějších pluginů, které často získávají svůj obsah pomocí ajaxového volání vracející JSON.</p> http://www.nullpointer.cz/zobrazovani-exceptions-v-ajaxovych-requestech-pomoci-struts2-a-jquery Refresh/reload ajaxového obsahu načteného pomocí JQuery Thu, 04 Oct 2012 17:36:11 GMT http://www.nullpointer.cz/refresh-reload-ajaxoveho-obsahu-nacteneho-pomoci-jquery <p>Je potřeba provést refresh/reload ajaxového obsahu načteného pomocí JQuery, např. pomocí metody load. Toto je užitečné velmi často, asi nejtypičtější případ je aktualizace obsahu po submitu formuláře. HTML div a kód JQuery může vypadat např. takto…</p> <h3>Problém</h3> <p>Je potřeba provést refresh/reload ajaxového obsahu načteného pomocí JQuery, např. pomocí metody load. Toto je užitečné velmi často, asi nejtypičtější případ je aktualizace obsahu po submitu formuláře. HTML div a kód JQuery může vypadat např. takto:</p> <p><strong>Javascript</strong></p> <pre class="cpp"><code>$(document).ready(function() { $("#ajaxObsah").load('&lt;vase_url_pro_nacteni_obsahu&gt;'); }</code></pre> <p><strong>HTML</strong></p> <pre class="html"><code>&lt;div id="ajaxObsah"&gt;&lt;/div&gt;</code></pre> <p>A nyní přidáme na stránku tlačítko a po kliknutí na něj budeme chtít provést refresh divu:</p> <p><strong>Javascript</strong></p> <pre class="cpp"><code>$(document).ready(function() { $("#ajaxObsah").load('&lt;vase_url_pro_nacteni_contentu&gt;'); $("button#tlacitko").click(function() { //tady bude kod pro refresh divu s id "ajaxObsah" }); }); }</code></pre> <p><strong>HTML</strong></p> <pre class="html"><code>&lt;div id="ajaxObsah"&gt;&lt;/div&gt; &lt;button id="tlacitko"&gt;&lt;/button&gt;</code></pre> <h3>Řešení teoreticky</h3> <p>Řešení by bylo velmi jednoduché, kdyby šlo napsat něco jako $(„ajaxObsah“)­.refresh(), ale to samozřejmě nejde. Další relativně jednoduchá možnost by byla zjistit si url načteného DIVu a zavolat znovu JQuery metodu load(). Jenže jsem nenašel způsob, jak se k url po načtení dostat, myslím si, že to ani nejde. <strong>Můj způsob řešení (rozhodně ne jediný) je následující workaround: při načtení divu pomocí metody load() využijeme toho, že v tuto chvíli ještě známe URL (zadáváme ho jako argument metody load()) a vytvoříme hidden s odvozeným ID (např. ajaxObsahHidden) a do value uložíme url. Takto se vždy k url dostaneme</strong> a můžeme pak znovu zavolat metodu load(). K tomu je nejideálnější vytvořit novou metodu load, která bude kromě načtení obsahu automaticky vytvářet hidden a nazveme ji např. loadContent. K tomu využijeme další JQuery kostrukci pro vytvoření nové metody. Takže kompletní řešení bude vypadat následovně:</p> <h3>Řešení prakticky</h3> <p><strong>Javascript</strong></p> <pre class="cpp"><code>$(document).ready(function() { /** * Vytvoří hidden, pokud již ale dle konvenčního ID existuje, pouze provede update hodnoty value */ function vytvorHidden(idHidden, name, value) { if ($("#" + idHidden).length &gt; 0) { $("#" + idHidden).val(value); } else { $("&lt;input&gt;&lt;/input&gt;").attr({id: idHidden, type: "hidden", name: name, value: value}).insertAfter($("body")); } } /** * Provede refresh ajaxového divu */ function refreshAjaxDiv(idDiv) { if (idDiv != undefined &amp;&amp; idDiv != '') { var href = $("#" + idDiv + 'Hidden').val(); $("#" + idDiv).load(href); } } /** * Definice nové metody, kterou nyní budeme používat místo standardní "load". Provede to stejné, jako standardní metoda "load", ale navíc ještě vytvoří hidden, do kterého uloží url. ID tohoto hidden je vygenerované podle konvence &lt;idDiv&gt;Hidden a znalost této konvence využívá funkce "refreshAjaxDiv" definovaná výše */ $.fn.loadContent = function(url) { return this.each(function() { vytvorHidden(this.id + "Hidden", "", url); $(this).load(url); }); } $("#ajaxObsah").loadContent('&lt;vase_url_pro_nacteni_contentu&gt;'); //Načte obsah divu "ajaxObsah" a současně vygeneruje hidden s id "ajaxDivHidden" $("button#tlacitko").click(function() { refreshAjaxDiv("ajaxObsah"); }); }); }</code></pre> <p><strong>HTML</strong></p> <pre class="html"><code>&lt;div id="ajaxObsah"&gt;&lt;/div&gt; &lt;button id="tlacitko"&gt;&lt;/button&gt;</code></pre> <h3>Závěr</h3> <p>Toto je zatím nejlepší funkční řešení, na které jsem přišel. Byť je v tom trošku „magie“ (kdesi se vytváří nějaký hidden s nějakým konvenčním ID, ke kterému se později „magicky“ přistupuje), tak přesto se nejedná úplně o špatné řešení, protože vývojář-uživatel je od této magie úplně odstíněn a jen si volá intuitivně funkce <em>loadContent</em> a <em>refreshAjaxDiv</em>. Budu velmi rád, když se v diskuzi podělíte o případné elegantnější řešení provedení refresh ajax DIVu.</p> http://www.nullpointer.cz/refresh-reload-ajaxoveho-obsahu-nacteneho-pomoci-jquery