Hlavní menu
Nástroje |
Jemný úvod od aplikaceTento dokument má za cíl sloužit jako pomocník pro "rychlé" zorientování se ve aplikaci a její architektuře. Adresářová struktura/doc - tento adresář by měl obsahovat dokumentaci... /logs - sem se mohou(podle nastavení v log4j.properties) zapisovat logy aplikace /scripts - obsahuje jednoduché skripty pro windows(bat) i linux(sh), spuštění aplikace, vytvoření war souboru, vytvoření dokumentace /sql - obsahuje sql scripty pro vytvoření potřebných tabulek a sekvencí. /src - adresář obsahuje všechny zdrojové a konfigurační soubory. /main /java/cz/zcu/kiv/spot - adresář, kde se nachází veškeré zdrojové kódy. /resources/static - adresář s javascripty, potřebnými obrázky a kaskádovými styly. /WEB-INF - adresář jako takový obsahuje konfigurační soubory pro spring + web.xml. /classes - obsahuje soubory s lokalizačními řetězci. /jsp - obsahuje veškeré jsp soubory v daných podadresářích. /properties - obsahuje konfigurační properties soubory /tld - potřebné tag libraries.. /test/java/cz/zcu/kiv/spot - adresář obsahující veškeré testy aplikace. /target - defaultní adresář pro vygenerovaný war soubor a vygenerovanou dokumentaci /site - adresář pro vygenerované stránky projektu /apidocs - pro javadoc /temp - obsahuje vzorové soubory pro import slov ze souboru a je pracovním adresářem při hromadném importu slov. Jmenné konvenceTato kapitola je v rámci SPOTu? docela problémová. Člověk se v aplikaci může setkat s tím, že jeden termín má i 3 ekvivalentní výrazy. Tomuto bych zde rád věnoval pár řádků. Zde jsou uvedená některá synonyma, na která jsem si vzpomněl:
Snažte se prosím tyto rady dodržovat a nevnášejte do aplikace ještě větší zmatek, než je v ní nyní ;) Dále by bylo více než vhodné třídy, metody a proměnné pojmenovávat anglicky a češtinu používat pouze v komentářích (bez diakritiky). Význam některých výrazů:
Nastavení IDEJe více méně na vás, jaké IDE si zvolíte. Ať už Netbeans nebo Eclipse (případně IntelliJ Idea nebo jiné) nabízí nepřeberné množství různých pluginů, které nám mají usnadnit práci. Dají se nainstalovat pluginy pro práci s Mavenem, Springem aj. Tato volba je opravdu jen na vás. Vhodné je použití Spring Tool Suite, což je vývojové prostředí založené na Eclipse, které usnadňuje vývoj aplikací s využitím Spring frameworku, Mavenu atd. EclipsePro windows i pro unix: turorial-spot-win32-ide-eclipse.zip [1,4 MB] Tutoriál pro spustění aplikace naleznete na stránce NasazeniAplikace Nejčastější klávesové zkratky, které mohou výrazným způsobem urychlit práci eclipse-zkratky.txt, další zajímavé informace na http://tipy.kiv.zcu.cz IDE, nastavení kódování projektuLinuxNastavení kódování celého projektu v IDE je velice důležité. Pod operačním systémem linux je automaticky v IDE Netbeans i Eclipse nastaveno kódování projektu (a všech jeho souborů) na UTF8. WindowsV případě použítí MS windows je situace závislá na konkrétním IDE:
SVNSVN pluginy pro eclipse
v případě prioblémů zkuste navštívit http://wiki.eclipse.org/SVN_Howto Nastavení SVN pro NetbeansPro unix: tutorial-spot-unix-ide-netbeans.zip [0,7 MB] Netbeans IDE maji plugin pro SVN defaultně zabudovaný. Pro týmovou spolupráci je vhodné zprovoznit SVN pro prostředí Netbeans. Pokud nemáte operační systém Windows Vista 64-bit, u kterého se zprovoznění nepovede, je to velmi jednoduché:
OdkazyDatový modelV současné době má datový model okolo 27 tabulek. Implementace
Konfigurační soubory
MVC - Model-view-controllerS principiálním popisem začnu od pohledu uživatele.
A teď, po trochu nudném úvodu, se dostáváme ke kořenu věci, tedy k tomu, jakým způsobem nám Spring zajistí propojení celé aplikace.
Servletovému kontejneru přijde požadavek, který obsahuje informace ve stylu: "Pošli mi potřebná data pro toto URL: http://ip.adresa.servletové.kontejneru:port/spot/sprava/uzivatele". Spring ví, že s daným URL je provázán konkrétní controller (mapování URL na controllery je ve <bean id="adminUsersController" class="cz.zcu.kiv.spot.controllers.AdminUsersController"> <property name="dictionaryManager" ref="dictionaryManager" /> <property name="pagingHelper" ref="pagingHelper" /> </bean> Id značí unikátní jméno, pod kterým je daná beana známa ostatním beanám, class je cesta ke controlleru a property říká, že je závislá na těch daných beanách. Toto provázání je zaznamenáno v beanách v souboru spot-servlet.xml. Konkrétně: <bean id="urlAbcMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default"> <property name="interceptors"> <list> <ref bean="settingInterceptor" /> <ref bean="authInterceptor" /> </list> </property> <property name="urlMap"> <map> . . <entry key="/sprava/uzivatele" value-ref="adminUsersController" /> . . </map> </property> <property name="alwaysUseFullPath" value="true" /> </bean> interceptoryJenže než přijde ke slovu konkrétní controller, tak v této beaně jsou přiřazeny 2 interceptory v části properties. Takovýto interceptor má na starosti provést implementovaný kód před tím, než předá řízení controlleru
Ve Spotu je implementována pouze metoda ControlleryNyní tedy konečně přichází ke slovu try { /* Pokud bylo zadane nove heslo */ if (!pass.equals("")) { user.setNpass(user.getPass()); } dictionaryManager.saveUser(user); mv.addObject("completeMsg", "editUser.complete"); } catch (Exception e) { logger.error("V aplikaci doslo k nasledujici chybe: " + e); mv.addObject("errorViewMsg", "error.unknow"); return; } Tak a nyní se dostáváme k tomu, jak se data z databáze dostanou ke controlleru.
Tento kousek kódu říká, že do daného Listu, se mají uložit všichni uživatelé. public void setDictionaryManager(DictionaryManager dictionaryManager) { this.dictionaryManager = dictionaryManager; } Zpět k volání public List<User> getAllUsers() { return userDao.getAllUsers(); } DAOZ něho vidíme, že je třeba jít do datové vrstvy aplikace k DAO rozhraním a jejich implementaci. Implementace public List<User> getAllUsers () { String sql = "SELECT * FROM users ORDER BY login"; return getJdbcTemplate().query(sql, new UserRowMapper ()); } Metoda private class UserRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(rs.getInt("users_id")); user.setLogin(rs.getString("login")); user.setPass(rs.getString("pass")); user.setFirstname(rs.getString("firstname")); user.setLastname(rs.getString("lastname")); user.setEmail(rs.getString("email")); user.setEmailpub(rs.getString("email_pub")); user.setHomepage(rs.getString("homepage")); user.setDescription(rs.getString("description")); user.setRights(rs.getInt("rights")); user.setActive(rs.getInt("active")); user.setActiveCode("active_code"); return user; } } Tak toto byla asi nejtěžší část celého seznámení se SPOTem. Doufám tedy, že jsem vám alespoň objasnil základní princip fungování aplikace. Na principu tohoto příkladu příkladu více méně funguje celá aplikace. Zpracování vyjímekLokalizace v JSPSamostatná stránka věnovaná lokalizaci aplikace SPOT. Ajax a knihovna DWR (Direct Web Remoting)Komunikaci mezi klientskou (javascript) a serverovou částí (java) zajišťuje knihovna DWR. Zprovoznění vyžaduje několik kroků, které nejsou úplně intuitivní, proto je zde popíšu. Nastavení spot-servlet.xmlZde je nutné určit, který controller bude obsluhovat volání javascriptových funkcí. V tomto případě musí třída WordShowController? obsahovat uvedené metody (ajaxWordEdit, ajaxSeeAlsoAdd,...). <bean id="wordShowController" class="cz.zcu.kiv.spot.controllers.WordShowController"> <property name="dictionaryManager" ref="dictionaryManager" /> <dwr:remote javascript="WordShowController"> <dwr:include method="ajaxWordEdit" /> <dwr:include method="ajaxSeeAlsoAdd" /> <dwr:include method="ajaxCommentAdd" /> <dwr:include method="ajaxCommentDelete" /> <dwr:include method="ajaxTransDelete" /> <dwr:include method="ajaxTransAdd" /> <dwr:include method="ajaxTransEdit" /> </dwr:remote> </bean> Poznámka: Pro testování je možné nastavit u tagu JavascriptJavascriptové funkce jsou umístěny v adresáři Ukázka javascriptové funkce, která volá metodu function ajaxWordEdit() { WordShowController.ajaxWordEdit(value("wordWord"), value("wordId"), value("usageId"), value("stateId"), ajaxWordEditCallback); } Callback funkce je zavolána po přijetí dat od metody controlleru a nebo po vytikání timeoutu. Přijatá data jsou uložená v parametru funkce (zde: wordData). Chybové stavy jsou řešeny vrácením function ajaxWordEditCallback(wordData) { if (wordData == null) { alert("Ke změně slova nedošlo. Nastala chyba."); return false; } else { /* zde bude nejaky kod, ktery provede zmenu na strance */ } } Serverová částV controlleru musí existovat metoda, kterou v javascriptu voláme. V níže uvedeném kódu je i ukázka, jak načíst kontext. public String[] ajaxWordEdit(String wordWord, int wordId, int usageId, int stateId) { /* nacteni web kontextu */ WebContext ctx = WebContextFactory.get(); HttpServletRequest request = ctx.getHttpServletRequest(); ... if ( /* nastala chyba */ ) { return null; } ... String[] infoToDisplay = {word.getWord(), word.getUrl(), state.getValue(), usage.getName()}; return infoToDisplay; } Logování a komentářeKdyž se dostanete k práci s neokomentovanou třídou, dookomentujte jí. Času je na to třeba minimum a když se nám pak předhodí log ze serveru s tím, že aplikace padá tehdy a tehdy, tak se alespoň bude dát z logu poznat, co se před spadnutím aplikace dělo a také proč spadla. Z toho plyne, ze nebude problém chybu opravit. Čtení logu má být jako čtení knihy s příběhem, v každé části by mělo být jasné co se děje. Zkuste psát minimálně dostačující dokumentační komentáře, které budou vašim následovníkům k něčemu a ne k ničemu. Postupem doby se došlo k doporučení používat ke komentářům sice češtinu, ale bez diakritiky. Vývoj SPOTu probíhá na operačním systému windows a linux, každý systém používá defaultně jiné kódování a i přes opratrnost v commitech se vyskytují neustále problémy s diakritikou ve zdrojových kódech. Čeština tedy bez diakritiky! TestováníBylo by více než vhodné, aby jste při práci s třídami, na kterých budete pracovat, k nim rovnou psali alespoň základní testy. Netvrdím, že můj nástřel testů je dostačující, na druhou stranu ho lze použít jako vodítko. Tipy a triky
Všeobecně
|