Izradite MVC web aplikaciju s gralovima

1. Pregled

U ovom uputstvu naučit ćemo kako stvoriti jednostavnu web aplikaciju pomoću Grala.

Grails (točnije, najnovija glavna verzija) je okvir izgrađen povrh projekta Spring Boot i koristi jezik Apache Groovy za razvoj web aplikacija.

Inspiriran je Rails Frameworkom za Ruby i izgrađen je oko filozofije konvencije o prekomjernoj konfiguraciji koja omogućuje smanjenje koda tipa.

2. Postavljanje

Prije svega, krenimo na službenu stranicu kako bismo pripremili okoliš. U vrijeme ovog vodiča, najnovija verzija je 3.3.3.

Jednostavno rečeno, postoje dva načina instaliranja Grailova: putem SDKMAN-a ili preuzimanjem distribucije i dodavanjem binarnih datoteka u varijablu okruženja PATH.

Postavljanje nećemo obrađivati ​​korak po korak, jer je dobro dokumentirano u dokumentima Grails.

3. Anatomija aplikacije za gralove

U ovom ćemo odjeljku bolje razumjeti strukturu aplikacije Grails. Kao što smo ranije spomenuli, Grails preferira konvenciju nad konfiguracijom, stoga mjesto datoteka definira njihovu svrhu. Pogledajmo što imamo u grails-app imenik:

  • imovina - mjesto na kojem pohranjujemo datoteke statičke imovine poput stilova, javascript datoteka ili slika
  • konf - sadrži datoteke za konfiguraciju projekta:
    • primjena.iml sadrži standardne postavke web aplikacija kao što su izvor podataka, vrste mima i ostale postavke povezane s Gralovima ili Proljećem
    • resursi.groovy sadrži definicije proljetnog graha
    • prijava.groovy sadrži konfiguraciju evidentiranja
  • kontroleri - odgovoran za rukovanje zahtjevima i generiranje odgovora ili njihovo delegiranje pogledima. Prema dogovoru, kada naziv datoteke završava s * Kontroler, okvir stvara zadano mapiranje URL-a za svaku radnju definiranu u klasi kontrolera
  • domena - sadrži poslovni model aplikacije Grails. GORM će svaki razred koji ovdje živi preslikati u tablice baze podataka
  • i18n - koristi se za potporu internacionalizaciji
  • u tome - ulazna točka prijave
  • usluge - ovdje će živjeti poslovna logika aplikacije. Prema dogovoru, Grails će stvoriti Spring Singleton grah za svaku uslugu
  • taglib - mjesto za prilagođene knjižnice oznaka
  • pogleda - sadrži poglede i predloške

4. Jednostavna web aplikacija

U ovom ćemo poglavlju stvoriti jednostavnu web aplikaciju za upravljanje studentima. Počnimo s pozivanjem CLI naredbe za stvaranje kostura aplikacije:

grails create-app

Kad se generira osnovna struktura projekta, prijeđimo na implementaciju stvarnih komponenata web aplikacija.

4.1. Sloj domene

Kako implementiramo web aplikaciju za rukovanje studentima, krenimo s generiranjem klase domene pod nazivom Student:

grails create-domain-class com.baeldung.grails.Student

I na kraju, dodajmo ime i prezime svojstva:

razred Student {String firstName String lastName}

Grails primjenjuje svoje konvencije i postavit će objektno-relacijsko mapiranje za sve klase smještene u grails-aplikacija / domena imenik.

Štoviše, zahvaljujući svojstvu GormEntity, sve klase domena imat će pristup svim CRUD operacijama, koji ćemo koristiti u sljedećem odjeljku za implementaciju usluga.

4.2. Uslužni sloj

Naša aplikacija rješava sljedeće slučajeve upotrebe:

  • Pregled popisa učenika
  • Stvaranje novih učenika
  • Uklanjanje postojećih učenika

Primijenimo ove slučajeve upotrebe. Započet ćemo generiranjem klase usluge:

grails create-service com.baeldung.grails.Student

Krenimo na grails-aplikacija / usluge direktoriju, pronađite našu novostvorenu uslugu u odgovarajućem paketu i dodajte sve potrebne metode:

@Transactional class StudentService {def get (id) {Student.get (id)} def list () {Student.list ()} def save (student) {student.save ()} def delete (id) {Student.get (id) .delete ()}}

Napominjemo da usluge prema zadanim postavkama ne podržavaju transakcije. Ovu značajku možemo omogućiti dodavanjem @Transational napomena razredu.

4.3. Sloj kontrolera

Da bismo učinili poslovnu logiku dostupnom korisničkom sučelju, stvorimo a StudentController pozivanjem na sljedeću naredbu:

grails create-controller com.baeldung.grails.Student

Prema zadanim postavkama, Gral ubrizgava grah po imenima. To znači da možemo lako ubrizgati StudentService pojedinačna instanca u naš kontroler deklariranjem varijable instance koja se zove studentiSlužba.

Sada možemo definirati radnje za čitanje, stvaranje i brisanje učenika.

class StudentController {def studentService def index () {response studentService.list ()} def show (Long id) {response studentService.get (id)} def create () {response new Student (params)} def save (Student student) {studentService.save (student) preusmjeravanje radnja: "indeks", metoda: "GET"} def delete (Long id) {studentService.delete (id) preusmjeravanje radnja: "index", metoda: "GET"}}

Prema dogovoru, the indeks() radnja ovog kontrolera preslikat će se na URI / student / indeks, the pokazati() djelovanje na / student / emisija i tako dalje.

4.4. Prikaži sloj

Nakon postavljanja naših radnji kontrolera, sada možemo nastaviti s izradom prikaza korisničkog sučelja. Stvorit ćemo tri Groovy Server stranice za popis, stvaranje i uklanjanje učenika.

Prema dogovoru, Grails će prikazati prikaz na temelju imena i radnje kontrolera. Na primjer,indeks () akcija iz StudentController riješit će se do /grails-app/views/student/index.gsp

Počnimo s provedbom pogleda / grails-app /views / student / index.gsp, koji će prikazati popis učenika. Upotrijebit ćemo oznaku stvoriti HTML tablicu koja prikazuje sve studente vraćene iz indeks() akcija u našem kontroleru.

Prema dogovoru, kada odgovorimo popisom objekata, Grails će nazivu modela dodati sufiks "List" tako da možemo pristupiti popisu studentskih objekata s varijablom studentList:

  • Stvoriti

Sada ćemo prijeći na pogled / grails-app /pogledi /student / create.gsp, što korisniku omogućuje stvaranje novih učenika. Upotrijebit ćemo ugrađeni oznaka koja prikazuje obrazac za sva svojstva datog graha:

Napokon, kreirajmo pogled / grails-app /pogledi /student / emisija.gsp za pregled i eventualno brisanje učenika.

Među ostalim oznakama, mi ćemo to iskoristiti , koji uzima grah kao argument i prikazuje sva njegova polja:

  • Popis učenika

4.5. Jedinični testovi

Gral uglavnom koristi Spock za testiranje. Ako niste upoznati sa Spockom, toplo preporučujemo da prvo pročitate ovaj vodič.

Počnimo s jedinstvenim testiranjem indeks() djelovanje naših StudentController.

Rugat ćemo se popis() metoda iz StudentService i testirati ako indeks() vraća očekivani model:

void "Testiranje radnje indeksa vraća točan model" () {given: controller.studentService = Mock (StudentService) {list () >> [new Student (firstName: 'John', lastName: 'Doe')]} kada: "Akcija indeksa se izvršava" controller.index (), a zatim: "Model je ispravan" model.studentList.size () == 1 model.studentList [0] .firstName == 'John' model.studentList [0]. lastName == 'Srna'}

Ajmo sada testirati izbrisati() akcijski. Provjerit ćemo je li izbrisati() je pozvan iz StudentService i provjerite preusmjeravanje na indeksnu stranicu:

void "Testiraj akciju brisanja pomoću instance" () {given: controller.studentService = Mock (StudentService) {1 * delete (2)} kada: "Instanca domene prosljeđuje se akciji brisanja" request.contentType = FORM_CONTENT_TYPE zahtjev .method = 'DELETE' controller.delete (2) zatim: "Korisnik je preusmjeren na indeks" response.redirectedUrl == '/ student / index'}

4.6. Testovi integracije

Dalje, pogledajmo kako stvoriti integracijske testove za sloj usluge. Uglavnom ćemo testirati integraciju s bazom podataka konfiguriranom u grails-app / conf / application.yml.

Prema zadanim postavkama, Grails koristi H2 bazu podataka u memoriji za ovu svrhu.

Prije svega, krenimo s definiranjem pomoćne metode za stvaranje podataka za popunjavanje baze podataka:

private Long setupData () {new Student (firstName: 'John', lastName: 'Doe') .save (flush: true, failOnError: true) new Student (firstName: 'Max', lastName: 'Foo') .save ( flush: true, failOnError: true) Student student = novi Student (firstName: 'Alex', lastName: 'Bar') .save (flush: true, failOnError: true) student.id}

Zahvaljujući @ Povrat napomena o našoj klasi integracijskog testa, svaka će se metoda izvoditi u zasebnoj transakciji, koja će se vratiti natrag na kraju testa.

Pogledajte kako smo implementirali test integracije za naš popis() metoda:

void "test list" () {setupData () when: List studentList = studentService.list () then: studentList.size () == 3 studentList [0] .lastName == 'Doe' studentList [1] .lastName == 'Foo' studentList [2] .lastName == 'Bar'}

Također, testirajmo izbrisati() metodu i potvrditi ako se ukupan broj učenika umanji za jedan:

void "test delete" () {Long id = setupData () očekujte: studentService.list (). size () == 3 kada: studentService.delete (id) sessionFactory.currentSession.flush () zatim: studentService.list () .size () == 2}

5. Pokretanje i postavljanje

Pokretanje i postavljanje aplikacija može se izvršiti pozivanjem jedne naredbe putem Grails CLI.

Za korištenje aplikacije upotrijebite:

grails run-app

Prema zadanim postavkama, Grails će postaviti Tomcat na priključak 8080.

Idemo do // localhost: 8080 / student / index da biste vidjeli kako izgleda naša web aplikacija:

Ako želite rasporediti svoju aplikaciju na spremnik servleta, upotrijebite:

gralovi rat

stvoriti ratni artefakt spreman za raspoređivanje.

6. Zaključak

U ovom smo se članku usredotočili na to kako stvoriti web aplikaciju Grails koristeći filozofiju prekomjerne konfiguracije. Također smo vidjeli kako izvoditi unit i integracijske testove sa Spock okvirom.

Kao i uvijek, sav ovdje korišten kod može se pronaći na GitHubu.