Développement rapide d'applications Web sur Vaadin et Spring Boot

CPAP


Le but de cet article est de systématiser le processus de développement d'une application web sur Vaadin 14 à l'aide de Spring Boot.


Avant de lire cet article, je recommande de lire le matériel suivant:



Impressions


Vaadin 14 est un outil plutôt pratique pour concevoir des applications Web, avant de le rencontrer, il a développé des interfaces graphiques uniquement sur JavaFX, Android et même J2ME, et en même temps évité le développement frontal (des connaissances de base en HTML, CSS, JS sont disponibles) car il ne pensait pas le mien.


Clause de non-responsabilité


Ceux qui n'ont pas encore travaillé avec Spring Boot recommandent de sauter un démarrage rapide en utilisant Spring Initializr, de revenir au matériel recommandé et d'essayer de tout configurer vous-même, ayant rencontré de nombreux problèmes différents, sinon à l'avenir il y aura des lacunes dans la compréhension de diverses choses.


Démarrage rapide


Créez un projet pour notre application web en utilisant Spring Initializr , les dépendances nécessaires pour notre petite application web:


  • Spring Data JPA (pour travailler avec la base de données)
  • Vaadin (pour le développement d'applications Web)
  • Lombok (pour réduire le code de la plaque de la chaudière)
  • Pilote MySQL (j'utilise mariadb, au printemps initializr'e ce n'est pas le cas)

Définition de application.properties et de la base de données


Le projet créé sur Spring Initializr est presque prêt à être exécuté, nous ne pouvons configurer application.properties qu'en spécifiant le chemin d'accès à la base de données, le nom d'utilisateur et le mot de passe


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 

Attention: ddl-auto

N'utilisez pas ddl-auto avec la valeur de mise à jour sur une base de données active ou lors du développement d'un projet, car il met automatiquement à jour le schéma de la base de données.
Options existantes pour ddl-auto:
create - créera une table dans la base de données, après avoir supprimé l'ancienne version de la table (perte de données en cas de changement de schéma)
validate - vérifie la table dans la base de données, si elle ne correspond pas à l'entité alors hibernate lèvera une exception
update - vérifie la table et la met à jour automatiquement sans supprimer les champs inexistants de l'entité
create-drop - vérifie la table, la crée ou la met à jour, puis la supprime, destinée aux tests unitaires


Avec le jeu de valeurs ddl-auto: update, hibernate crée automatiquement une table dans la base de données basée sur notre essence, car nous faisons un simple carnet d'adresses puis créons une classe de contact.


Contact.class
 @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; } 

Créons une interface pour travailler avec la base de données et ajoutons une méthode qui renvoie List depuis Spring Data JPA renvoie par défaut Iterable au lieu de List.

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

Le développement de l'interface sur Vaadin comprend l'ajout de composants d'entrée, de visualisation et de formulaires d'interaction aux objets de mise en page pour le positionnement nécessaire des éléments. Une liste de tous les composants peut être consultée sur le site officiel du framework.


La page principale de notre application sera ContactList. Nous hériterons de tous les objets des pages créées d' AppLayout - il s'agit d'une présentation typique d'une application Web composée de:


  • Navbar (en-tête)
  • Tiroir (barre latérale)
  • Le contenu
    Dans le même temps, des composants sont ajoutés à Navbar et Drawer, et un composant est défini sur Contenu en tant que contenu, par exemple, VerticalLayout dans lequel les éléments utilisateur seront placés dans une disposition verticale.

La page d'édition et de création de contacts sera ManageContact, et nous y implémenterons l'interface HasUrlParameter pour transférer l'ID du contact, lorsque cette interface est activée, le paramètre doit être transmis à la page.
Afin de lier une page à une URL spécifique, l'annotation Route est utilisée:


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

Créer une liste de contacts


Dans le constructeur de l'objet ContactList, spécifiez les composants utilisés en faisant d'abord d'eux les champs de l'objet. Comme les données seront extraites de la base de données, il est nécessaire de connecter le référentiel au champ objet.


 @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); } } 

À propos d'Autowired (mis à jour)

N'essayez pas d'accéder à contactRepository à partir du constructeur d'un objet; cela entraînera certainement une NullPointerException, l'accès à partir de méthodes avec annotation PostConstruct ou de méthodes d'un objet déjà créé.
Sur une astuce de zesetup : contactRepository, vous pouvez injecter via le constructeur:


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

Comme conseil de markellg : il convient également de noter que lorsque vous utilisez Spring version 4.3 et supérieure, l'annotation Autowired sur le constructeur est facultative si la classe contient un seul constructeur.


Le composant VerticalLayout a été ajouté à la classe ContactList pour l'agencement vertical des éléments dans le contenu, nous y ajouterons RouterLink (pour aller à la page de création de contact) et Grid pour afficher le tableau. La grille est tapée par l'objet Contact afin que nous puissions charger des données à partir de la liste et elles remontent automatiquement lorsque la méthode setItems () est appelée;


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

Le comportement de création automatique de colonne ne nous intéresse pas, car dans le cadre de l'article, il convient de montrer l'ajout de colonnes, et l'affichage de boutons pour supprimer ou modifier des contacts.


Pour remplir le tableau, nous obtiendrons les données de contactRepository, pour cela nous allons créer une méthode avec annotation PostConstruct


Remplir une table avec fillGrid ()
  @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 est utilisé pour ajouter des colonnes avec des boutons d'édition et de suppression, nous transmettons le nom du bouton aux arguments du constructeur et un gestionnaire de clic de bouton.


 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 }})); 

Résultat

Liste de contacts


Création d'une page d'édition de contact


La page d'édition de contact accepte le paramètre comme identifiant de contact, nous devons donc implémenter la méthode setParameter ():


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

L'ajout de composants est similaire à ContactList, mais dans ce cas, nous n'utilisons pas VerticalLayout, mais utilisons un balisage spécial FormLayout pour afficher ces formulaires. Nous remplissons le formulaire avec des données n'utilisant plus la méthode avec l'annotation PostConstruct, mais après avoir obtenu le numéro de contact à partir de l'URL, car la chaîne: 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(); }); } } 

Résultat

Modification des contacts


Résultats: Vaadin 14 est un cadre plutôt pratique pour créer des applications Web simples, en l'utilisant, vous pouvez rapidement créer une application avec seulement des connaissances Java dans les bagages, et cela fonctionnera. Mais malheureusement, toute l'interface est créée côté serveur et les ressources sont bien plus nécessaires que d'utiliser HTML5 + JS. Ce cadre est plus adapté aux petits projets qui doivent être réalisés rapidement sans étudier les technologies frontales.


Cet article a montré comment créer rapidement et facilement une application Web sans concevoir de base de données au préalable, éviter les longues configurations xml et à quelle vitesse vous pouvez développer une interface Web. Pour la plupart, Spring Boot et Spring Data JPA simplifient la vie des développeurs et simplifient le développement. L'article ne révélera rien de nouveau aux développeurs déjà établis, mais aidera le débutant à commencer à maîtriser le framework Spring.


Référentiel avec projet


Des erreurs de grammaire et de ponctuation sont possibles dans l'article; lors de la détection, veuillez envoyer un

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


All Articles