Sprievodca JavaLite - Vytvorenie aplikácie RESTful CRUD

1. Úvod

JavaLite je kolekcia rámcov na zjednodušenie bežných úloh s ktorými sa musí každý vývojár pri tvorbe aplikácií vyrovnať.

V tomto výučbe sa pozrieme na funkcie JavaLite zamerané na vytvorenie jednoduchého API.

2. Inštalácia

V celom tomto výučbe vytvoríme jednoduchú aplikáciu RESTful CRUD. Za týmto účelom použijeme ActiveWeb a ActiveJDBC - dva z rámcov, s ktorými JavaLite integruje.

Začnime teda a pridajme prvú závislosť, ktorú potrebujeme:

 org.javalite activeweb 1.15 

Artefakt ActiveWeb obsahuje ActiveJDBC, takže ho nie je potrebné pridávať osobitne. Upozorňujeme, že najnovšiu verziu aktívneho webu nájdete v Maven Central.

Druhá závislosť, ktorú potrebujeme, je databázový konektor. V tomto príklade budeme používať MySQL, takže musíme pridať:

 mysql mysql-konektor-java 5.1.45 

Najnovšiu závislosť mysql-connector-java nájdete opäť na serveri Maven Central.

Posledná závislosť, ktorú musíme pridať, je niečo špecifické pre JavaLite:

 org.javalite activejdbc-instrumentation 1.4.13 inštrument triedy procesov 

Najnovší doplnok inštrumentácie activejdbc nájdete aj v Maven Central.

Keď to všetko máme pripravené a predtým, ako začneme s entitami, tabuľkami a priradeniami, zaistíme to jedna z podporovaných databáz je funkčná. Ako sme už povedali, použijeme MySQL.

Teraz sme pripravení začať s objektovo-relačným mapovaním.

3. Objektovo-relačné mapovanie

3.1. Mapovanie a prístrojové vybavenie

Začnime tým vytvorenie a Výrobok triedy, ktorá bude našou hlavnou entitou:

verejná trieda Produkt {}

A tiež vytvorte pre ňu zodpovedajúcu tabuľku:

VYTVORIŤ TABUĽKOVÉ VÝROBKY (id int (11) DEFAULT NULL auto_increment PRIMÁRNY KLÍČ, meno VARCHAR (128));

Nakoniec môžeme upraviť naše Výrobok triedy na vykonanie mapovania:

verejná trieda Produkt rozširuje Model {}

Musíme len predĺžiť org.javalite.activejdbc.Model trieda. ActiveJDBC odvodzuje parametre schémy DB z databázy. Vďaka tejto schopnosti nie je potrebné pridávať getry a settery ani nijakú anotáciu.

ActiveJDBC to navyše automaticky rozpozná Výrobok trieda musí byť namapovaná na PRODUKTY stôl. Využíva anglické skloňovanie na prevod singulárnej formy modelu na množné číslo tabuľky. A áno, funguje to aj na výnimky.

Existuje jedna posledná vec, ktorú budeme musieť urobiť, aby naše mapovanie fungovalo: prístrojové vybavenie. Prístrojové vybavenie je ďalším krokom vyžadovaným programom ActiveJDBC to nám umožní hrať sa s našimi Výrobok trieda, akoby mala getre, setre a metódy podobné DAO.

Po spustení prístrojovej techniky budeme môcť robiť napríklad tieto veci:

Produkt p = nový produkt (); p.set ("meno", "chlieb"); p.saveIt ();

alebo:

Zoznam produktov = Product.findAll ();

Toto je kde activejdbc-prístrojové vybavenie prichádza plugin. Pretože už máme závislosť v našom pom, mali by sme vidieť, ako sa triedy zostavujú počas zostavovania:

... [INFO] --- activejdbc-instrumentation: 1.4.11: instrument (predvolené) @ javalite --- ************************* **** ZAČNITE INSTRUMENTÁCIU ***************************** Adresár: ... \ tutoriály \ java-lite \ target \ classes Instrumentované trieda: ... / tutoriály / java-lite / cieľ / triedy / aplikácia / modely / Product.class **************************** * KONIEC INSTRUMENTÁCIA ***************************** ...

Ďalej vytvoríme jednoduchý test, aby sme sa uistili, že to funguje.

3.2. Testovanie

Nakoniec otestujeme naše mapovanie a vykonáme tri jednoduché kroky: otvoríme pripojenie k databáze, uložíme nový produkt a stiahneme ho:

@Test public void givenSavedProduct_WhenFindFirst_ThenSavedProductIsReturned () {Base.open ("com.mysql.jdbc.Driver", "jdbc: mysql: // localhost / dbname", "user", "heslo"); Produkt toSaveProduct = nový Produkt (); toSaveProduct.set ("meno", "chlieb"); toSaveProduct.saveIt (); Produkt savedProduct = Product.findFirst ("name =?", "Bread"); assertEquals (toSaveProduct.get ("meno"), savedProduct.get ("meno")); }

Všimnite si, že to všetko (a viac) je možné len s prázdnym modelom a prístrojovým vybavením.

4. Ovládače

Teraz, keď je naše mapovanie pripravené, môžeme začať uvažovať o našej aplikácii a metódach CRUD.

Na to využijeme radiče, ktoré spracúvajú požiadavky HTTP.

Poďme vytvoriť naše ProductsController:

@RESTful verejná trieda ProductsController rozširuje AppController {public void index () {// ...}}

S touto implementáciou bude program ActiveWeb automaticky mapovať index () metódu na nasledujúci URI:

//:/Produkty

Ovládače s poznámkami @RESTful, poskytujú pevnú sadu metód automaticky mapovaných na rôzne URI. Pozrime sa na tie, ktoré budú užitočné pre náš príklad CRUD:

Metóda ovládačaMetóda HTTPURI
VYTVORIŤvytvoriť ()POST// hostiteľ: port / produkty
PREČÍTAJTE SI JEDENšou()ZÍSKAJTE// hostiteľ: port / products / {id}
PREČÍTAJTE SI VŠETKOindex ()ZÍSKAJTE// hostiteľ: port / produkty
AKTUALIZÁCIAaktualizácia ()PUT// hostiteľ: port / products / {id}
ODSTRÁNIŤzničiť ()ODSTRÁNIŤ// hostiteľ: port / products / {id}

A ak k tomu pridáme tento súbor metód ProductsController:

@RESTful verejná trieda ProductsController rozširuje AppController {public void index () {// kód na získanie všetkých produktov} public void create () {// kód na vytvorenie nového produktu} public void update () {// kód na aktualizáciu existujúceho product} public void show () {// kód na nájdenie jedného produktu} public void zničiť () {// kód na odstránenie existujúceho produktu}}

Pred prechodom na našu logickú implementáciu sa krátko pozrieme na pár vecí, ktoré musíme nakonfigurovať.

5. Konfigurácia

ActiveWeb je založený väčšinou na konvenciách, príkladom je štruktúra projektu. Projekty ActiveWeb musia dodržiavať preddefinované rozloženie balíka:

src | ---- hlavný | ---- java.app | | ---- konfigurácia | | ---- radiče | | ---- modely | ---- zdroje | ---- webapp | ---- WEB-INF | ---- zobrazenia

Je potrebné sa pozrieť na jeden konkrétny balík - app.config.

Vo vnútri tohto balíka vytvoríme tri triedy:

public class DbConfig extends AbstractDBConfig {@Override public void init (AppContext appContext) {this.configFile ("/ database.properties"); }}

Táto trieda konfiguruje databázové pripojenia pomocou súboru vlastností v koreňovom adresári projektu obsahujúceho požadované parametre:

development.driver = com.mysql.jdbc. Driver driver.username = užívateľ development.password = heslo vývoj.url = jdbc: mysql: // localhost / dbname

Takto sa vytvorí pripojenie, ktoré automaticky nahradí to, čo sme vykonali v prvom riadku nášho testu mapovania.

Druhá trieda, ktorú musíme zahrnúť dovnútra app.config balíček je:

public class AppControllerConfig extends AbstractControllerConfig {@Override public void init (AppContext appContext) {add (new DBConnectionFilter ()). to (ProductsController.class); }}

Tento kódnaviaže pripojenie, ktoré sme práve nakonfigurovali, na náš radič.

Tretia trieda budenakonfigurovať kontext našej aplikácie:

verejná trieda AppBootstrap rozširuje Bootstrap {public void init (kontext AppContext) {}}

Po vytvorení troch tried je posledná vec, ktorá sa týka konfigurácie vytváranie našich web.xml spis pod webapp / WEB-INF adresár:

   dispečer org.javalite.activeweb.RequestDispatcher vylúčenia css, obrázky, js, ico kódovanie dispečera UTF-8 / * 

Teraz, keď je konfigurácia hotová, môžeme pokračovať a pridať našu logiku.

6. Implementácia CRUD Logic

Vďaka schopnostiam podobným DAO, ktoré poskytujú naše Výrobok triedy, je to super jednoduché pridať základnú funkčnosť CRUD:

@RESTful verejná trieda ProductsController rozširuje AppController {súkromný mapovač ObjectMapper = nový ObjectMapper (); public void index () {List products = Product.findAll (); // ...} public void create () {Map payload = mapper.readValue (getRequestString (), Map.class); Produkt p = nový produkt (); p.fromMap (užitočné zaťaženie); p.saveIt (); // ...} public void update () {Map payload = mapper.readValue (getRequestString (), Map.class); Reťazec id = getId (); Produkt p = Product.findById (id); p.fromMap (užitočné zaťaženie); p.saveIt (); // ...} public void show () {String id = getId (); Produkt p = Product.findById (id); // ...} public void destru () {String id = getId (); Produkt p = Product.findById (id); p.delete (); // ...}}

Ľahké, že? Zatiaľ to však nič nevracia. Aby sme to dosiahli, musíme vytvoriť niekoľko pohľadov.

7. Pohľady

ActiveWeb používa FreeMarker ako šablónový nástroj a všetky jeho šablóny by mali byť umiestnené pod src / main / webapp / WEB-INF / zobrazenia.

Vo vnútri tohto adresára umiestnime naše zobrazenia do priečinka s názvom Produkty (rovnako ako náš kontrolór). Vytvorme našu prvú šablónu s názvom _product.ftl:

{"id": $ {product.id}, "name": "$ {product.name}"}

V tejto chvíli je zrejmé, že sa jedná o odpoveď JSON. Samozrejme to bude fungovať iba pre jeden produkt, takže poďme na to a vytvorme ďalšiu šablónu s názvom index.ftl:

[]

Týmto sa v podstate vykreslí kolekcia s názvom Produkty, pričom každý z nich je naformátovaný _product.ftl.

Nakoniec musíme spojiť výsledok z nášho kontrolóra s príslušným pohľadom:

@RESTful verejná trieda ProductsController rozširuje AppController {public void index () {List products = Product.findAll (); pohľad ("výrobky", výrobky); render (); } public void show () {String id = getId (); Produkt p = Product.findById (id); pohľad („produkt“, s); render ("_ produkt"); }}

V prvom prípade priraďujeme Produkty zoznam do našej kolekcie šablón s názvom tiež Produkty.

Potom, keďže nešpecifikujeme žiadne zobrazenie, index.ftl bude použitý.

V druhej metóde priraďujeme produkt p na živel výrobok v zobrazení a výslovne hovoríme, ktorý pohľad sa má vykresliť.

Mohli by sme tiež vytvoriť pohľad message.ftl:

{"message": "$ {message}", "code": $ {code}}

A potom to zavolajte z ktorejkoľvek z našich ProductsControllerMetóda:

view ("správa", "Vyskytla sa chyba.", "kód", 200); render ("správa");

Poďme sa teraz pozrieť na naše finále ProductsController:

@RESTful verejná trieda ProductsController rozširuje AppController {súkromný mapovač ObjectMapper = nový ObjectMapper (); public void index () {view ("products", Product.findAll ()); render (). contentType ("application / json"); } public void create () {Map payload = mapper.readValue (getRequestString (), Map.class); Produkt p = nový produkt (); p.fromMap (užitočné zaťaženie); p.saveIt (); view ("správa", "ID produktu bolo úspešne uložené" + p.get ("id"), "kód", 200); render ("správa"); } public void update () {Map payload = mapper.readValue (getRequestString (), Map.class); Reťazec id = getId (); Produkt p = Product.findById (id); if (p == null) {view ("message", "Product id" + id + "not found.", "code", 200); render ("správa"); návrat; } p.fromMap (užitočné zaťaženie); p.saveIt (); view ("správa", "ID produktu bolo úspešne aktualizované" + id, "kód", 200); render ("správa"); } public void show () {String id = getId (); Produkt p = Product.findById (id); if (p == null) {view ("message", "Product id" + id + "not found.", "code", 200); render ("správa"); návrat; } zobrazenie ("produkt", s); render ("_ produkt"); } public void destru () {String id = getId (); Produkt p = Product.findById (id); if (p == null) {view ("message", "Product id" + id + "not found.", "code", 200); render ("správa"); návrat; } p.delete (); view ("správa", "ID produktu bolo úspešne odstránené" + id, "kód", 200); render ("správa"); } @Override chránený reťazec getContentType () {return "application / json"; } @Override chránený reťazec getLayout () {return null; }}

V tomto okamihu je naša aplikácia hotová a sme pripravení ju spustiť.

8. Spustenie aplikácie

Použijeme doplnok Jetty:

 org.eclipse.jetty jetty-maven-plugin 9.4.8.v20171121 

Nájdite najnovší doplnok jetty-maven v Maven Central.

A sme pripravení, môžeme spustiť našu aplikáciu:

mvn mólo: spustiť

Vytvorme niekoľko produktov:

$ curl -X POST // localhost: 8080 / products -H 'content-type: application / json' -d '{"name": "Water"}' {"message": "Úspešne uložené ID produktu 1", " kód ": 200}
$ curl -X POST // localhost: 8080 / products -H 'content-type: application / json' -d '{"name": "Bread"}' "" správa ":" Úspešne uložené ID produktu 2 "," kód ": 200}

.. prečítajte si ich:

$ curl -X GET // localhost: 8080 / products [{"id": 1, "name": "Water"}, {"id": 2, "name": "Bread"}]

.. aktualizujte jeden z nich:

$ curl -X PUT // localhost: 8080 / products / 1 -H 'content-type: application / json' -d '{"name": "Juice"}' {"message": "Úspešne aktualizované ID produktu 1" , „code“: 200}

... prečítajte si ten, ktorý sme práve aktualizovali:

$ curl -X GET // localhost: 8080 / products / 1 {"id": 1, "name": "Juice"}

Nakoniec môžeme jednu vymazať:

$ curl -X DELETE // localhost: 8080 / products / 2 {"message": "ID produktu 2 bolo úspešne odstránené", "kód": 200}

9. Záver

JavaLite má veľa nástrojov, ktoré vývojárom pomáhajú spustite aplikáciu behom niekoľkých minút. Avšak zatiaľ čo zakladanie na konvenciách vedie k čistejšiemu a jednoduchšiemu kódu, pochopeniu pomenovania a umiestnenia tried, balíkov a súborov chvíľu trvá, kým pochopia.

Toto bol iba úvod do ActiveWebu a ActiveJDBC, nájdenie ďalšej dokumentácie na ich webových stránkach a hľadanie aplikácie našich produktov v projekte Github.


$config[zx-auto] not found$config[zx-overlay] not found