web-dev-qa-db-fra.com

Spring Web MVC: utilisez le même mappage de requête pour le paramètre de requête et la variable de chemin

Existe-t-il un moyen d'exprimer que ma méthode de contrôleur Spring Web MVC doit être mise en correspondance soit par une demande de remise d'un ID dans le cadre du chemin URI ...

@RequestMapping(method=RequestMethod.GET, value="campaigns/{id}")
public String getCampaignDetails(Model model, @PathVariable("id") Long id) {

... ou si le client envoie l'ID en tant que paramètre de requête HTTP dans le style ...

@RequestMapping(method=RequestMethod.GET, value="campaigns")
public String getCampaignDetails(Model model, @RequestParam("id") Long id) {

Cela me semble un schéma d'URL du monde réel assez courant où je ne veux pas ajouter de code en double, mais je n'ai pas encore trouvé de réponse. Tous les conseils sont les bienvenus.

EDIT: Il s'avère qu'il semble actuellement (avec Spring MVC <= 3.0) aucun moyen d'y parvenir, voir discussion dans la réponse de Javi.

37
ngeek

Vous pouvez définir l'URL de mappage pour la même fonction et définir l'ID comme facultatif.

@RequestMapping(method=RequestMethod.GET, value={"/campaigns","/campaigns/{id}"})
public String getCampaignDetails(Model model,
     @RequestParam(value="id", required=false) Long id,
     @PathVariable("id") Long id2)
{
}

bien qu'il soit également mappé lorsque id n'est pas envoyé, mais vous pouvez contrôler cela à l'intérieur de la méthode.

EDIT : La solution précédente ne fonctionne pas car @PathVariable n'est pas défini sur null lorsqu'il n'y a pas {null} et il ne peut pas mapper l'URL (merci ngeek). Je pense alors que la seule solution possible est de créer deux méthodes mappées chacune avec son @MappingRequest et à l'intérieur de l'un d'eux, appelez l'autre fonction ou redirigez vers l'autre URL (rediriger: ou transférer: préfixes Spring). Je sais que cette solution n'est pas ce que vous recherchez, mais pensez que c'est le mieux que vous puissiez faire. En effet, vous ne dupliquez pas de code mais vous créez une autre fonction pour gérer une autre URL.

50
Javi

Si vous voulez toujours vous en tenir à l'approche PathVariable et si vous obtenez 400 erreurs syntaxiquement incorrectes, suivez cette approche-

 @RequestMapping(method=RequestMethod.GET, value={"campaigns/{id}","campaigns"})
                         public String getCampaignDetails(Model model,
                         @PathVariable Map<String, String> pathVariables) 
   {

     System.out.println(pathVariables.get("id"));

   }
4
Vivek

Le @RequestMapping l'annotation prend désormais en charge la définition de l'attribut path au lieu de name ou value. Avec path, vous pouvez obtenir le mappage souhaité par cette question:

@RequestMapping(method=RequestMethod.GET, path="campaigns/{id}")
public String getCampaignDetails(Model model, @PathVariable("id") Long id) {

@RequestMapping(method=RequestMethod.GET, value="campaigns")
public String getCampaignDetails(Model model, @RequestParam("id") Long id) {
2
Jpnh