Application Spring Boot CRUD avec Thymeleaf

Application CRUD pour bottes à ressort avec thymeleaf

1. Vue d'ensemble

L'implémentation des couchesDAO qui fournissent la fonctionnalité CRUD sur les entitésJPA peut être une tâche répétitive et chronophage que nous voulons éviter dans la plupart des cas. Heureusement,Spring Boot facilite la création d'applications CRUD via une couche de référentiels CRUD standard basés sur JPA.

In this tutorial, we’ll learn how to develop a CRUD web application with Spring Boot and Thymeleaf.

Lectures complémentaires:

Paramètres de demande de ressort avec Thymeleaf

Apprenez à utiliser les paramètres de requête avec Spring et Thymeleaf.

Read more

Modification du répertoire de modèles Thymeleaf dans Spring Boot

En savoir plus sur les emplacements des modèles Thymeleaf.

Read more

2. Les dépendances Maven

Dans ce cas, nous nous fierons àspring-boot-starter-parent pour une gestion simple des dépendances, la gestion des versions et la configuration des plug-ins. Par conséquent, nous n’aurons pas besoin de spécifier les versions des dépendances du projet dans notre fichierpom.xml, sauf pour remplacer la version Java:


    org.springframework.boot
    spring-boot-starter-parent
    2.0.6.RELEASE


    
        org.springframework.boot
        spring-boot-starter-web
    
    
        org.springframework.boot
        spring-boot-starter-thymeleaf
    
    
        org.springframework.boot
        spring-boot-starter-data-jpa
    
    
        com.h2database
        h2
    


    1.8

Nous devons remplacer la propriété<java.version> car la version Java par défaut définie parspring-boot-starter-parent est 1.6.

3. La couche de domaine

Avec toutes les dépendances de projet déjà en place, implémentons maintenant une couche de domaine naïve.

Par souci de simplicité, cette couche comprendra une seule classe qui sera responsable de la modélisation des entitésUser:

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @NotBlank(message = "Name is mandatory")
    private String name;

    @NotBlank(message = "Email is mandatory")
    private String email;

    // standard constructors / setters / getters / toString
}

Gardons à l'esprit que nous avons annoté la classe avec l'annotation@Entity. Therefore, the JPA implementation, which is Hibernate, in this case, will be able to perform CRUD operations on the domain entities. Pour un guide d'introduction à Hibernate, visitez notre tutoriel surHibernate 5 with Spring.

De plus, nous avons contraint les champsname etemail avec la contrainte@NotBlank. Cela implique que nous pouvons utiliser Hibernate Validator pour valider les champs contraints avant de persister ou de mettre à jour une entité dans la base de données.

Pour les bases à ce sujet, consultezour associated tutorial on Bean Validation.

4. La couche de référentiel

À ce stade, notre exemple d'application Web ne fait rien. Mais cela est sur le point de changer.

Spring Data JPAallows us to implement JPA-based repositories (a fancy name for the DAO pattern implementation) with minimal fuss.

Spring Data JPA est un composant clé desspring-boot-starter-data-jpa de Spring Boot qui facilite l'ajout de fonctionnalités CRUD via une puissante couche d'abstraction placée au-dessus d'une implémentation JPA. Cette couche d'abstraction nous permet d'accéder à la couche de persistance sans avoir à fournir nos propres implémentations DAO à partir de zéro.

Pour fournir à notre application les fonctionnalités CRUD de base sur les objetsUser, tout ce que nous devons faire est d'étendre l'interfaceCrudRepository:

@Repository
public interface UserRepository extends CrudRepository {}

Et c'est tout! En étendant simplement l’interface deCrudRepository, Spring Data JPA nous fournira des implémentations pour les méthodes CRUD du référentiel.

5. La couche contrôleur

Thanks to the layer of abstraction that spring-boot-starter-data-jpa places on top of the underlying JPA implementation, we can easily add some CRUD functionality to our web application through a basic web tier.

Dans notre cas, une seule classe de contrôleur suffira pour gérer les requêtes HTTP GET et POST, puis les mapper aux appels à notre implémentationUserRepository.

La classe de contrôleur repose sur certaines des fonctionnalités clés de Spring MVC. Pour un guide détaillé sur Spring MVC, consultez nosSpring MVC tutorial.

Commençons par les méthodesshowSignUpForm() etaddUser() du contrôleur.

Le premier affichera le formulaire d'inscription de l'utilisateur, tandis que le second conservera une nouvelle entité dans la base de données après avoir validé les champs contraints.

Si l'entité ne réussit pas la validation, le formulaire d'inscription sera de nouveau affiché. Sinon, une fois que l'entité aura été enregistrée, la liste des entités persistantes sera mise à jour dans la vue correspondante:

@Controller
public class UserController {

    @GetMapping("/signup")
    public String showSignUpForm(User user) {
        return "add-user";
    }

    @PostMapping("/adduser")
    public String addUser(@Valid User user, BindingResult result, Model model) {
        if (result.hasErrors()) {
            return "add-user";
        }

        userRepository.save(user);
        model.addAttribute("users", userRepository.findAll());
        return "index";
    }

    // additional CRUD methods
}

Dans leUserController we aura également la méthodeshowUpdateForm() qui est responsable de la récupération de l'entitéUser qui correspond auxid fournis à partir de la base de données.

Si l'entité existe, elle sera transmise en tant qu'attribut de modèle à la vue du formulaire de mise à jour, le formulaire peut donc être rempli avec les valeurs des champsname etemail:

@GetMapping("/edit/{id}")
public String showUpdateForm(@PathVariable("id") long id, Model model) {
    User user = userRepository.findById(id)
      .orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));

    model.addAttribute("user", user);
    return "update-user";
}

Enfin, nous avons les méthodesupdateUser() etdeleteUser() dans la classeUserController.

Le premier persistera l'entité mise à jour dans la base de données, tandis que le dernier supprimera l'entité donnée.

Dans les deux cas, la liste des entités persistantes sera mise à jour en conséquence:

@PostMapping("/update/{id}")
public String updateUser(@PathVariable("id") long id, @Valid User user,
  BindingResult result, Model model) {
    if (result.hasErrors()) {
        user.setId(id);
        return "update-user";
    }

    userRepository.save(user);
    model.addAttribute("users", userRepository.findAll());
    return "index";
}

@GetMapping("/delete/{id}")
public String deleteUser(@PathVariable("id") long id, Model model) {
    User user = userRepository.findById(id)
      .orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
    userRepository.delete(user);
    model.addAttribute("users", userRepository.findAll());
    return "index";
}

6. Le calque de vue

À ce stade, nous avons implémenté une classe de contrôleur fonctionnel qui effectue des opérations CRUD sur les entitésUser. Even so, there’s still a missing component in this schema: the view layer.

Sous le dossiersrc/main/resources/templates, nous devons créer les modèles HTML requis pour afficher le formulaire d'inscription, le formulaire de mise à jour et afficher la liste des entitésUser persistantes,

Comme indiqué dans l'introduction, nous utiliserons Thymeleaf comme moteur de modèle sous-jacent pour analyser les fichiers de modèle.

Voici la section pertinente du fichieradd-user.html:

Notice how we’ve used the @\{/adduser} URL expression to specify the form’s action attribute and the $\{} variable expressions for embedding dynamic content in the template, such as the values of the name and email fields and the post-validation errors.

Semblable àadd-user.html, voici à quoi ressemble le modèleupdate-user.html:

Enfin, nous avons le fichierindex.html qui affiche la liste des entités persistantes ainsi que les liens pour éditer et supprimer les entités existantes:

No users yet!

Users

Name Email Edit Delete
Edit Delete

Add a new user

Par souci de simplicité, les modèles semblent plutôt squelettiques et ne fournissent que les fonctionnalités requises sans ajouter decosmetics inutiles.

Pour donner aux modèles un aspect amélioré et accrocheur sans passer trop de temps sur HTML / CSS, nous pouvons facilement utiliser un kit d'interface utilisateurTwitter Bootstrap gratuit, commeShards.

7. Lancer l'application

Enfin, définissons le point d’entrée de l’application. Comme la plupart des applications Spring Boot, nous pouvons le faire avec une ancienne méthodemain():

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Maintenant, frappons "Exécuter" dans notre IDE, puis ouvrons notre navigateur et pointez-le vershttp://localhost:8080.

Si la compilation a réussi à compilerwe should see a basic CRUD user dashboard with links for adding new entities and for editing and removing existing ones.

8. Conclusion

Dans ce tutoriel, nous avons appris à créer une application Web de base CRUD avec Spring Boot et Thymeleaf.

Comme d'habitude, tous les exemples de code présentés dans l'article sont disponibles suron GitHub.