[JAVA] Conseils pour la gestion des énumérations avec thymeleaf

Cette année, j'ai été impliqué dans un projet qui utilise Spring boot, et j'ai organisé les résultats obtenus sur thymeleaf et enum.

Choses qui reviennent souvent lorsque vous recherchez sur Google avec "Thym leaf enum"

Avec Spring ou Spring Boot, il est courant d'utiliser Thymeleaf avec le moteur de modèle. Il est courant d'utiliser enum pour gérer la valeur et le nom d'affichage de la zone de sélection du formulaire de saisie.

Extrait de https://www.baeldung.com/thymeleaf-enums, mais lorsque vous google, vous pouvez voir quelques exemples comme celui ci-dessous.

<select name="color">
    <option th:each="colorOpt : ${T(com.baeldung.thymeleaf.model.Color).values()}"
        th:value="${colorOpt}" th:text="${colorOpt.displayValue}"></option>
</select>

Il existe également un tel exemple pour juger s'il s'agit d'une énumération spécifique en jugeant la valeur initiale.

<div th:if="${widget.color == T(com.baeldung.thymeleaf.model.Color).RED}">

La difficulté avec cette méthode

Je le vois souvent, mais quand je dis que c'est le meilleur, je ne peux rien dire.

  1. La partie FQDN du type est difficile à lire (il n'y a pas de quantité d'informations pendant une longue période)
  2. Si vous essayez de revoir la structure du package, vous devez modifier le modèle
  3. Même lors du changement de nom enum, le modèle doit être modifié.

Le fait est que quelque chose qui n'a rien à voir avec le modèle entre en jeu, ce qui a un impact négatif sur la lisibilité et la maintenabilité. Si vous voulez faire quelque chose qui fonctionne pour le moment, cette méthode est bonne, mais c'est un peu douloureux.

Que faire

Fondamentalement, il est préférable d'implémenter ce que vous utilisez dans le modèle enum. En outre, plutôt que d'appeler directement à partir du modèle, il est préférable de modifier le formulaire pour transmettre l'instance requise depuis le contrôleur.

Lors de l'utilisation de tous les éléments d'énumération (boîte de sélection, etc.)

Java enum a une méthode implicite appelée public static T [] values (). Utilisez ceci pour énumérer tous les éléments. (En parlant de classiques, c'est une histoire classique.)


public enum UserStatus {
   ACTIVE(1, "Efficacité"),
   INACTIVE(0, "Invalide"),
   PENDING(2, "en attente"),
   FORBIDDEN(3, "Arrêt forcé")
   ;

   private final int value;

   private final String viewName;

   private UserStatus(int value, String viewName) {
       this.value = value;
       this.viewName = viewName;
   }

   public int getValue() {
       return this.value;
   }

   public String getViewName() {
       return this.viewName;
   }

}

@Controller
public class SampleController

@RequestGetMapping
public ModelAndView index() {
   ModelAndView model = new ModelAndView();
   model.setAttribute("statusList", UserStatus.values());
   return model;
}

<select name="status">
    <option th:each="status : statusList}" 
            th:value="${status.value}" th:text="${status.viewName}">
    </option>
</select>

Recevoir l'entrée du formulaire sous forme d'énumération

La méthode ci-dessus n'est pas pratique pour recevoir la valeur sous forme d'énumération. enum a implicitement déclaré des méthodes, name () et valueOf (String name).

Le nom donné à name () est retourné, et valueOf (String name) retourne l'instance correspondante si les noms correspondent. Spring les utilisera pour vous.

<select name="status">
    <option th:each="status : statusList}" 
            th:value="${status.name()}" th:text="${status.viewName}">
    </option>
</select>
public class NewUserForm {

  private UserStatus status;

  // ... 

}
@RequestPutMapping
public ModelAndView create(NewUserForm form) {
   ModelAndView model = new ModelAndView();
   // ... 
   return model;
}

Ensuite, la sélection dans le formulaire peut être mappée à enum et reçue.

Jugement d'une énumération spécifique

Il existe un moyen d'ajouter une méthode appelée isXXX à enum.


public enum UserStatus {
   // ...

   public boolean isActive() {
       return this == ACTIVE;
   }

   public boolean isForbidden() {
       return this == FORBIDDEN;
   }

}
<div th:if="${status.isForbidden()}">
    This user is forbidden.
</div>

Cette méthode isXXX est utile non seulement pour les modèles mais également pour l'écriture de logique métier. Par exemple, si vous souhaitez limiter uniquement les utilisateurs valides, cela ressemble à ceci.


public class User {

  //...

  private final UserStatus status;

  public UserStatus getStatus() {
     return this.status
  }

}

   List<User> users = ...
   List<User> activeUsers = users.stream()
                                 .filter(x -> x.getStatus().isActive())
                                 .collect(Collectors.toList());

Résumé

Vous pouvez ou non trouver les meilleures pratiques autour de vous. Aussi, il est rare de savoir si la méthode trouvée par la recherche est adaptée ou non à votre situation actuelle. Les modèles sont faciles à intégrer à de nombreux intérêts, vous devez donc prendre beaucoup de décisions lors de leur mise en œuvre.

Lien de référence

Recommended Posts

Conseils pour la gestion des énumérations avec thymeleaf
Conseils pour gérer les pseudo-éléments dans Selenium
astuces pour java.nio.file.Path
Créer un extrait pour Thymeleaf dans VS Code
Conseils pour générer des fichiers pour les projets d'éclipse avec Gradle
Conseils pour définir le délai initial pour Poller dans XML
Conseils pour bien utiliser Canvas avec Xcode
Gestion des erreurs avec Graphql-ruby
Conseils d'utilisation de Salesforce SOAP et de l'API Bulk en Java
Reportez-vous à enum dans Thymeleaf
[Ruby] Gestion des exceptions dans les fonctions
Collection Gradle TIPS (pour moi)
[Java] Conseils pour l'écriture de la source
Techniques de gestion des exceptions en Java
Conseils pour généraliser l'API
Tirez parti de l'un ou l'autre pour la gestion des exceptions individuelles dans l'API Java Stream