Il est possible de tester si un paramètre existe ou non dans une URL avec Spring?
Ci-dessous, mon code actuel, mais peut-être que if (status == null) est un peu sale non?
@GetMapping
public ResponseEntity<?> getAllTasks(@RequestParam(value = "status", required = false) Integer status) {
if(status == null) {
return new ResponseEntity<>(this.taskResource.findAll(), HttpStatus.OK);
}
return new ResponseEntity<>(this.tacheResource.getTachesByEtat(status), HttpStatus.OK);
}
La méthode getAllTasks () sera appelée dans différents cas:
C'est pourquoi j'essaie de trouver une autre façon de faire ce test.
Pouvez-vous m'aider?
Merci.
3 Réponses :
Regardez vers le bas, à la fin de cette réponse, la meilleure solution.
La meilleure approche consiste à suivre le modèle de responsabilité unique .
Comme votre URL peut être appelée de deux manières différentes, pourquoi ne pas la diviser et laisser chacune implémenter sa propre logique?
@GetMapping(params = { "status", "date" })
Spring s'en chargera magnifiquement. p>
Notez que lorsque vous utilisez une seule propriété de valeur avec une Annotation , vous n'avez pas besoin de la spécifier explicitement.
Edit: étant donné que cela peut avoir pour effet de produire une collision de mappage, une alternative encore meilleure à @RequestParam consiste à utiliser @PathVariable pour le code * WithStatus > endpoint.
@GetMapping
public ResponseEntity<?> getAllTasks() {
return ResponseEntity.ok().body(this.taskResource.findAll());
}
@GetMapping(params = "status")
public ResponseEntity<?> getAllTasksWithStatus(@RequestParam("status") final int status) {
return ResponseEntity.ok().body(this.tacheResource.getTachesByEtat(status));
}
Lorsqu'il s'agit d'URL complexes et longues, il y a deux chemins à emprunter.
Utilisez @PathVariable (s), tels que
/{status}/{date}/{name}
Ou lancez une requête HTTP POST . Ici, vous pouvez personnaliser le body à votre guise. Je fais généralement des requêtes POST lorsque je traite des appels HTTP complexes.
Dernière modification, espérons-le:
vous pouvez affiner le mappage en spécifiant les paramètres de requête souhaités.
@GetMapping("/status/{status}")
public ResponseEntity<?> getAllTasksWithStatus(@PathVariable("status") final int status) {
return ResponseEntity.ok().body(this.tacheResource.getTachesByEtat(status));
}
Plus de conflits;)
Comme params est un array, vous pouvez spécifier plusieurs valeurs avec
@GetMapping
public ResponseEntity<?> getAllTasks() {
return ResponseEntity.ok().body(this.taskResource.findAll());
}
@GetMapping
public ResponseEntity<?> getAllTasksWithStatus(@RequestParam("status") final int status) {
return ResponseEntity.ok().body(this.tacheResource.getTachesByEtat(status));
}
Comment géreriez-vous la même URL mais paramètre facultatif dans ce cas, puisque vos 2 contrôleurs pointent vers la même URL. Ne pensez-vous pas que cela créera une ambiguïté?
@ArpitAgrawal il y a un compromis ici. Le paramètre de requête "optionnel" n'est plus optionnel, au profit d'une solution plus propre, d'un point de vue architectural.
@LppEdd En effet, c'est la meilleure solution pour moi. Cependant, j'ai eu une erreur: "Cartographie ambigüe". vous pouvez trouver mon problème ici: stackoverflow.com/questions/54676727/ …
@ N.Lamblin m'a laissé lancer un projet Spring.
@ N.Lamblin vérifie si la solution proposée vous convient. Si la modification de votre schéma d'URL n'est pas possible, la solution facultative est celle qu'il vous faut. Cependant je pense que les paramètres optionnels ne devraient pas être utilisés
@ N.Lamblin Je viens de penser à un autre intéressant. Faites-moi savoir ce que vous pensez de celui ci-dessus.
Le seul problème que je vois avec la solution de @PathVariable est si j'ai besoin de plusieurs paramètres à l'avenir. Par exemple, le statut, la date et le nom. Je dois créer une URL telle que / status / {status} / date / {date} / name / {name} . C'est un peu étrange non? Merci pour votre réponse.
@ Solution N.Lamblin trouvée. Voir ma modification. Regardez comment j'ai ajouté le ("/") uniquement au premier point de terminaison, getAllTasks. Il vous suffit d'appeler le point de terminaison avec "/". Pensez-vous que c'est acceptable?
@ N.Lamblin J'ai également donné mon avis sur les URL complexes.
Votre dernière modification est la réponse parfaite! Maintenant, je dois trouver comment spécifier plusieurs paramètres (pour comprendre et apprendre correctement Spring). Quelque chose comme @GetMapping (params = "status", params = "date") .
@ N.Lamblin btw, merci pour ce "défi". C'était amusant d'écrire cette réponse.
@LppEdd grand merci !!!! Où trouvez-vous ces informations? Sur la documentation? Parce que je ne les ai pas trouvés.
@ArpitAgrawal Regardez la réponse :).
@ N.Lamblin Je l'ai trouvé en lisant la documentation RequestMapping docs.spring.io/spring-framework/docs/current/javadoc-api/org /…
@ N.Lamblin J'ai également répondu à votre autre question, à titre de référence. Il sera visité plus de fois dans le futur.
@ N.Lamblin oui, j'ai aussi vu ceci ici: stackoverflow.com/questions/15853035/... . Oui. En effet, un bon moyen.
En fonction de votre version Java, vous pouvez utiliser Facultatif et isPresent () (mais vous devrez obtenir la valeur de votre status code > variable utilisant status.get()):@GetMapping
public ResponseEntity<?> getAllTasks(@RequestParam("status") Optional<Integer> status) {
if(!status.isPresent()) {
return new ResponseEntity<>(this.taskResource.findAll(), HttpStatus.OK);
}
return new ResponseEntity<>(this.tacheResource.getTachesByEtat(status.get()), HttpStatus.OK);
}
Vous pouvez utiliser Facultatif dans l'annotation requestParam. @RequestParam ("status") facultatif
Après cela, vous pouvez vérifier si l'état est présent: status.ifPresent()
Je m'en tiendrai à la solution de LppEdd
il est principalement basé sur des opinions et vous pouvez utiliser
Objects.isNull (status)