Schnelle Entwicklung von Webanwendungen auf Vaadin und Spring Boot

CPAP


In diesem Artikel wird der Prozess der Entwicklung einer Webanwendung auf Vaadin 14 mithilfe von Spring Boot systematisiert.


Bevor ich diesen Artikel lese, empfehle ich, das folgende Material zu lesen:



Impressionen


Vaadin 14 ist ein recht praktisches Tool zum Entwerfen von Webanwendungen. Bevor es sich mit ihm befasste, entwickelte es grafische Oberflächen nur für JavaFX, Android und sogar J2ME und vermied gleichzeitig die Frontend-Entwicklung (Grundkenntnisse in HTML, CSS und JS sind vorhanden), weil es nicht glaubte meins.


Haftungsausschluss


Diejenigen, die noch nicht mit Spring Boot gearbeitet haben, empfehlen, einen schnellen Einstieg mit Spring Initializr zu überspringen, zum empfohlenen Material zurückzukehren und alles selbst zu konfigurieren, da sie auf viele verschiedene Probleme gestoßen sind. Andernfalls wird es in Zukunft Lücken im Verständnis verschiedener Dinge geben.


Schnellstart


Erstellen Sie ein Projekt für unsere Webanwendung mit dem Spring Initializr , den notwendigen Abhängigkeiten für unsere kleine Webanwendung:


  • Spring Data JPA (zum Arbeiten mit der Datenbank)
  • Vaadin (für die Entwicklung von Webanwendungen)
  • Lombok (zur Reduzierung des Kesselschildcodes)
  • MySQL-Treiber (Ich benutze Mariadb, im Frühjahr ist es initializr'e nicht)

Festlegen von application.properties und der Datenbank


Das mit Spring Initializr erstellte Projekt ist fast betriebsbereit. Sie müssen lediglich application.properties konfigurieren, indem Sie den Datenbankpfad, den Benutzernamen und das Kennwort angeben


spring.datasource.url = jdbc:mariadb://127.0.0.1:3306/test spring.datasource.username=user spring.datasource.password=password spring.jpa.hibernate.ddl-auto=update 

Achtung: ddl-auto

Verwenden Sie ddl-auto nicht mit dem Aktualisierungswert in einer Live-Datenbank oder beim Entwickeln eines Projekts, da dadurch das Datenbankschema automatisch aktualisiert wird.
Bestehende Optionen für ddl-auto:
create - erstellt eine Tabelle in der Datenbank, nachdem zuvor die alte Version der Tabelle gelöscht wurde (Datenverlust bei Schemaänderung)
validieren - Überprüft die Tabelle in der Datenbank. Wenn sie nicht mit der Entität übereinstimmt, löst der Ruhezustand eine Ausnahme aus
update - Überprüft die Tabelle und aktualisiert sie automatisch, ohne dass nicht vorhandene Felder aus der Entität entfernt werden
create-drop - Überprüft die Tabelle, erstellt oder aktualisiert sie und löscht sie anschließend, um sie für Komponententests zu verwenden


Mit dem Wertesatz ddl-auto: update erstellt der Ruhezustand automatisch eine Tabelle in der Datenbank, basierend auf unserer Essenz, weil Wir erstellen ein einfaches Adressbuch und dann eine Kontaktklasse.


Kontakt.Klasse
 @Entity(name = "Contacts") @Getter @Setter @EqualsAndHashCode public class Contact { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String firstName; private String secondName; private String fatherName; private String numberPhone; private String email; } 

Erstellen wir eine Schnittstelle für die Arbeit mit der Datenbank und fügen eine Methode hinzu, die List since zurückgibt Spring Data JPA gibt standardmäßig Iterable anstelle von List zurück.

ContactRepository.class
 public interface ContactRepository extends CrudRepository<Contact, Integer> { List<Contact> findAll(); } 

Die Schnittstellenentwicklung in Vaadin umfasst das Hinzufügen von Komponenten für Eingabe-, Visualisierungs- und Interaktionsformulare zu Layoutobjekten für die erforderliche Positionierung von Elementen. Eine Liste aller Komponenten finden Sie auf der offiziellen Website des Frameworks.


Die Hauptseite unserer Anwendung wird ContactList sein. Wir übernehmen alle Objekte der erstellten Seiten von AppLayout - dies ist ein typisches Layout einer Webanwendung, bestehend aus:


  • Navbar (Header)
  • Schublade (Seitenleiste)
  • Inhalt
    Gleichzeitig werden Komponenten zu Navbar und Drawer hinzugefügt, und eine Komponente wird auf Content als Content festgelegt, z. B. VerticalLayout, in dem Benutzerelemente in vertikaler Anordnung platziert werden.

Die Seite zum Bearbeiten und Erstellen von Kontakten lautet ManageContact. In dieser Seite wird die HasUrlParameter-Schnittstelle implementiert, um die Kontakt-ID zu übertragen. Wenn diese Schnittstelle aktiviert ist, muss der Parameter an die Seite übergeben werden.
Um eine Seite an eine bestimmte URL zu binden, wird die Annotation Route verwendet:


 @Route("contacts") public class ContactList extends AppLayout {} @Route("manageContact") public class ManageContact extends AppLayout implements HasUrlParameter<Integer> {} 

Erstellen Sie eine Kontaktliste


Geben Sie im Konstruktor des ContactList-Objekts die verwendeten Komponenten an, indem Sie sie zunächst zu den Feldern des Objekts machen. Da die Daten aus der Datenbank übernommen werden, muss das Repository mit dem Objektfeld verbunden werden.


 @Route("contacts") public class ContactList extends AppLayout { VerticalLayout layout; Grid<Contact> grid; RouterLink linkCreate; @Autowired ContactRepository contactRepository; public ContactList(){ layout = new VerticalLayout(); grid = new Grid<>(); linkCreate = new RouterLink(" ",ManageContact.class,0); layout.add(linkCreate); layout.add(grid); addToNavbar(new H3(" ")); setContent(layout); } } 

Über Autowired (aktualisiert)

Versuchen Sie nicht, vom Konstruktor eines Objekts aus auf contactRepository zuzugreifen, da dies mit Sicherheit eine NullPointerException, den Zugriff von Methoden mit PostConstruct-Annotation oder Methoden eines bereits erstellten Objekts verursacht.
Auf einen Tipp von zesetup : contactRepository können Sie durch den Konstruktor einfügen:


 ContactRepository contactRepository; @Autowired public ContactList(ContactRepository contactRepository){ this.contactRepository = contactRepository; 

Ein Tipp von markellg : Es ist auch erwähnenswert, dass bei Verwendung von Spring Version 4.3 und höher die Autowired-Annotation für den Konstruktor optional ist, wenn die Klasse einen einzelnen Konstruktor enthält.


Die VerticalLayout-Komponente wurde der ContactList-Klasse für die vertikale Anordnung der Elemente im Inhalt hinzugefügt. Sie wird mit RouterLink (zum Aufrufen der Seite zum Erstellen von Kontakten) und mit Grid (Raster) zum Anzeigen der Tabelle versehen. Das Raster wird vom Contact-Objekt typisiert, damit wir Daten aus der Liste laden können. Diese werden automatisch aufgerufen, wenn die setItems () -Methode aufgerufen wird.


 Grid<Contact> grid; public ContactList(){ grid = new Grid<>(); //      grid = new Grid<>(Contact.class); //      ,       } 

Das Verhalten der automatischen Spaltenerstellung interessiert uns nicht, weil Im Rahmen des Artikels lohnt es sich, das Hinzufügen von Spalten und die Anzeige von Schaltflächen zum Löschen oder Bearbeiten von Kontakten zu zeigen.


Um die Tabelle zu füllen, erhalten wir die Daten von contactRepository. Dazu erstellen wir eine Methode mit PostConstruct-Annotation


Eine Tabelle mit fillGrid () füllen
  @PostConstruct public void fillGrid(){ List<Contact> contacts = contactRepository.findAll(); if (!contacts.isEmpty()){ //     grid.addColumn(Contact::getFirstName).setHeader(""); grid.addColumn(Contact::getSecondName).setHeader(""); grid.addColumn(Contact::getFatherName).setHeader(""); grid.addColumn(Contact::getNumberPhone).setHeader(""); grid.addColumn(Contact::getEmail).setHeader("E-mail"); //     grid.addColumn(new NativeButtonRenderer<Contact>("", contact -> { UI.getCurrent().navigate(ManageContact.class,contact.getId()); })); grid.addColumn(new NativeButtonRenderer<Contact>("", contact -> { Dialog dialog = new Dialog(); Button confirm = new Button(""); Button cancel = new Button(""); dialog.add("     ?"); dialog.add(confirm); dialog.add(cancel); confirm.addClickListener(clickEvent -> { contactRepository.delete(contact); dialog.close(); Notification notification = new Notification(" ",1000); notification.setPosition(Notification.Position.MIDDLE); notification.open(); grid.setItems(contactRepository.findAll()); }); cancel.addClickListener(clickEvent -> { dialog.close(); }); dialog.open(); })); grid.setItems(contacts); } } 

NativeButtonRenderer wird zum Hinzufügen von Spalten mit Schaltflächen zum Bearbeiten und Löschen verwendet. Der Schaltflächenname wird an die Konstruktorargumente und an einen Schaltflächen-Klick-Handler übergeben.


 grid.addColumn(new NativeButtonRenderer<Contact>("", contact -> { //DO SOMETHING })); grid.addColumn(new NativeButtonRenderer<Contact>("", new ClickableRenderer.ItemClickListener<Contact>() { @Override public void onItemClicked(Contact contact) { //DO SOMETHING }})); 

Ergebnis

Kontaktliste


Erstellen einer Kontaktbearbeitungsseite


Die Kontaktbearbeitungsseite akzeptiert den Parameter als Kontakt-ID, daher müssen wir die setParameter () -Methode implementieren:


  @Override public void setParameter(BeforeEvent beforeEvent, Integer contactId) { id = contactId; if (!id.equals(0)){ addToNavbar(new H3(" ")); } else { addToNavbar(new H3(" ")); } fillForm(); //  } 

Das Hinzufügen von Komponenten ähnelt ContactList, nur verwenden wir in diesem Fall nicht VerticalLayout, sondern FormLayout-Spezialmarkup, um solche Formulare anzuzeigen. Wir füllen das Formular nicht mehr mit Daten, die die Methode mit PostConstruct-Annotation verwenden, sondern nachdem wir die Kontaktnummer aus der URL erhalten haben, weil die Kette: Object constructor -> @PostConstruct -> Override


Managecontact.class
 @Route("manageContact") public class ManageContact extends AppLayout implements HasUrlParameter<Integer> { Integer id; FormLayout contactForm; TextField firstName; TextField secondName; TextField fatherName; TextField numberPhone; TextField email; Button saveContact; @Autowired ContactRepository contactRepository; public ManageContact(){ //    contactForm = new FormLayout(); firstName = new TextField(""); secondName = new TextField(""); fatherName = new TextField(""); numberPhone = new TextField(" "); email = new TextField(" "); saveContact = new Button(""); //     contactForm.add(firstName, secondName,fatherName,numberPhone,email,saveContact); setContent(contactForm); } @Override public void setParameter(BeforeEvent beforeEvent, Integer contactId) { id = contactId; if (!id.equals(0)){ addToNavbar(new H3(" ")); } else { addToNavbar(new H3(" ")); } fillForm(); } public void fillForm(){ if (!id.equals(0)){ Optional<Contact> contact = contactRepository.findById(id); contact.ifPresent(x -> { firstName.setValue(x.getFirstName()); secondName.setValue(x.getSecondName()); fatherName.setValue(x.getFatherName()); numberPhone.setValue(x.getNumberPhone()); email.setValue(x.getEmail()); }); } saveContact.addClickListener(clickEvent->{ //       Contact contact = new Contact(); if (!id.equals(0)){ contact.setId(id); } contact.setFirstName(firstName.getValue()); contact.setSecondName(secondName.getValue()); contact.setFatherName(fatherName.getValue()); contact.setEmail(email.getValue()); contact.setNumberPhone(numberPhone.getValue()); contactRepository.save(contact); Notification notification = new Notification(id.equals(0)? "  ":"  ",1000); notification.setPosition(Notification.Position.MIDDLE); notification.addDetachListener(detachEvent -> { UI.getCurrent().navigate(ContactList.class); }); contactForm.setEnabled(false); notification.open(); }); } } 

Ergebnis

Kontakt bearbeiten


Ergebnisse: Vaadin 14 ist ein recht praktisches Framework für die Erstellung einfacher Webanwendungen. Mit ihm können Sie schnell eine Anwendung erstellen, die nur Java-Kenntnisse im Gepäck hat, und sie wird funktionieren. Leider wird die gesamte Oberfläche auf der Serverseite erstellt, und Ressourcen sind viel notwendiger als die Verwendung von HTML5 + JS. Dieses Framework eignet sich eher für kleine Projekte, die schnell erledigt werden müssen, ohne sich mit Front-End-Technologien zu befassen.


Dieser Artikel zeigte, wie Sie schnell und einfach eine Webanwendung erstellen können, ohne zuvor eine Datenbank zu entwerfen, lange XML-Konfigurationen vermeiden und wie schnell Sie eine Webschnittstelle entwickeln können. Spring Boot und Spring Data JPA erleichtern Entwicklern größtenteils das Leben und vereinfachen die Entwicklung. Der Artikel wird den bereits etablierten Entwicklern nichts Neues verraten, aber dem Anfänger helfen, das Spring-Framework zu meistern.


Repository mit Projekt


Grammatik- und Interpunktionsfehler sind im Artikel möglich, bei Entdeckung senden Sie bitte ein persönliches

Source: https://habr.com/ru/post/de480852/


All Articles