La partie Socle de cette solution est initialement développée avec Java 17. Elle utilise donc certaines fonctionnalités intéressantes (et pour certaines relativement récentes) de Java :
Par contre, certaines nouveautés ne me semble pas pertinente voire génantes. Donc ne sont pas autorisées sur le projet les fonctionnalités suivantes :
Les record de Java ont l’avantage de ne plus nécessiter de coder les getter et setter.
Mais attention ! Un record est une structure de données dont tous les attributs sont finaux. Donc aucun setter n’est disponible !!!
Pour les besoins de notre code, il peut être utile de créer un constructeur spécifique. Ceci est possible à condition d’appeler le constructeur natif du record avec une valeur par défaut pour chaque attribut (false, new ArrayList<>(), new HashMap<>() ou null). Exemple :
/** Constructeur vide */
public PageDto() {
this(new ArrayList<>(), null, null, null, false, false);
}
/** Constructeur par défaut */
public PageDto(List<BlocDto> blocs, String conditionVisibilite) {
this(blocs, conditionVisibilite, null, null, false, false);
}
Pour les besoins de SpringDataMongo, si la classe décrit une structure de données stockée dans MongoDB et qu’un constructeur est codé explicitement, il faut créer un constructeur complet pour MongoDB. Ce constructeur doit
/**
* Constructeur contenant tous les attributs mais avec le premier en dernier pour fournit à SpringDataMongo un constructeur à utitiliser (les
* setter n'existe pas dans un record). De plus, pour les mêmes raisons mais avec Jackson, il faut ajouter un @JsonCreator sur le constructeur et
* un @JsonProperty sur chaque paramètre.
*/
@PersistenceConstructor
@JsonCreator
public PageDto(@JsonProperty("conditionVisibilite") String conditionVisibilite, @JsonProperty("titre") String titre,
@JsonProperty("titreAriane") String titreAriane, @JsonProperty("exclueDuFilDariane") Boolean exclueDuFilDariane,
@JsonProperty("specifiqueAlaDemarche") Boolean specifiqueAlaDemarche, @JsonProperty("blocs") List<BlocDto> blocs) {
this(blocs, conditionVisibilite, titre, titreAriane, exclueDuFilDariane, specifiqueAlaDemarche);
}
Seule la classe StringUtils de Spring peut être utilisée (org.springframework.util). La méthode la plus utilisée est hasLength.
Toute donnée doit être validée en entrée de toute API exposée par le socle.
La validation doit être la plus précise possible. Plusieurs REGEXs sont disponibles dans la classe RegexUtils du projet socle-commun. Si de nouvelles REGEXs doivent être créées pour correspondre au plus près au format d’une donnée, elles doivent être créées.
Pour valider un paramètre unique dans une méthode publiques d’un contrôlleur REST, il faut utiliser l’annotation @Pattern:
ResponseEntity<byte[]> obtenirContenuDuCaptcha(//
@Pattern(regexp = RegexUtils.ALPHABETIQUE_ETENDUE) String get, //
@Pattern(regexp = RegexUtils.ALPHANUMERIQUE) String c, //
@Pattern(regexp = RegexUtils.NOMBRE) String t);
Pour valider un objet passer dans un corps de message, il faut demander la validation de l’objet avec l’annotation @Valid et utiliser l’annnotation @Pattern pour valider chacun des membres de cette classe :
String soumettreUnTeledossier(@Valid @RequestBody DonneesDeSoumissionDto dto);
public class DonneesDeSoumissionDto {
@Pattern(regexp = RegexUtils.CODE_DEMARCHE)
private String codeDemarche;
private Map<@Pattern(regexp = RegexUtils.DONNEE_SOUMISE_CLEF) String, @Pattern(regexp = RegexUtils.DONNEE_SOUMISE_VALEUR) String> donnees = new HashMap<>();
@Pattern(regexp = RegexUtils.ID)
private String idBrouillon;
...
}
Pour information, dans les écrans WEB de SwaggerUI, les contraintes sur les membres de classes soumises (en bas de page, dans la partie schéma) sont bien décrits avec leurs validations. Mais, pour les paramètres d’appels de type simple (chaîne de caractères, nombres, …), les contraintes ne s’affichent pas dans la page. Néanmoins, si une donnée invalide est saisie, SwaggerUI n’exécute pas la requête car il sait que la donnée est invalide mais il affiche un message. Toutes les validations de données sont présentes dans le swagger (document JSON descriptif technique).
L’annotation @Autowired permet d’injecter un composant dans un autre.
Depuis des années, l’habitude / le standard est d’utiliser l’annotation @Autowired sur chaque membre d’un composant qui est un composant à injecter (tout comme pour les valeurs de configuration avec @Value).
Mais, depuis quelques mois/années est poussée une autre façon de faire : l’usage du constructeur. Sonar, depuis peu, pousse aussi cette pratique avec la règle RSPEC-4288.
Sur le principe, l’idée est bonne :
La documentation de l’injection de dépendance de Spring est documentée ici.
Les consignes sont donc :