Pouvons-nous avoir plus d'une annotation @Path
Pour la même REST c'est-à-dire que la méthode exécutée est la même, mais elle est exécutée lors de l'accès à plusieurs URL?
Par exemple: je veux exécuter la méthode searchNames()
sur http://a/b/c
Et http://a/b
.
Vous ne pouvez pas avoir plusieurs annotations @Path
Sur une seule méthode. Il provoque une erreur de syntaxe "annotation en double".
Cependant, il existe plusieurs façons de mapper efficacement deux chemins vers une méthode.
L'annotation @Path
Dans JAX-RS accepte les paramètres, dont les valeurs peuvent être restreintes à l'aide d'expressions régulières.
Cette annotation:
@Path("a/{parameter: path1|path2}")
permettrait à la méthode d'être atteinte par des demandes pour /a/path1
et /a/path2
. Si vous devez travailler avec des sous-chemins, échappez les barres obliques: {a:path1\\/subPath1|path2\\/subPath2}
Vous pouvez également configurer une redirection. Voici un moyen de le faire dans Jersey (l'implémentation de référence de JAX-RS), en définissant une autre sous-ressource. Ceci est juste un exemple, si vous préférez une autre façon de gérer les redirections, n'hésitez pas à l'utiliser.
@Path("basepath")
public class YourBaseResource {
//this gets injected after the class is instantiated by Jersey
@Context
UriInfo uriInfo;
@Path("a/b")
@GET
public Responce method1(){
return Response.ok("blah blah").build();
}
@Path("a/b/c")
@GET
public Response method2(){
UriBuilder addressBuilder = uriInfo.getBaseUriBuilder();
addressBuilder.path("a/b");
return Response.seeOther(addressBuilder.build()).build();
}
}
Si vous avez souvent besoin de telles fonctionnalités, je vous suggère d'intercepter les demandes entrantes à l'aide d'un filtre de servlet et de réécrire les chemins à la volée. Cela devrait vous aider à conserver toutes les redirections au même endroit. Idéalement, vous pourriez utiliser une bibliothèque prête. UrlRewriteFilter
peut faire l'affaire, tant que vous êtes bien avec une licence BSD (consultez leur site de code Google pour plus de détails)
Une autre option consiste à gérer cela avec un proxy installé devant votre application Java. Vous pouvez configurer un serveur Apache pour offrir des règles de mise en cache et de réécriture de base sans compliquer votre Java code.
Comme expliqué dans réponse de Tom , vous ne pouvez pas utiliser plus d'un @Path
annotation sur une seule méthode, car vous allez rencontrer error: duplicate annotation
au moment de la compilation.
Je pense que le moyen le plus simple de contourner cela est d'utiliser la surcharge de méthode:
@Path("{foo}")
public Response rest(@PathParam("foo") final String foo) {
return this.rest(foo, "");
}
@Path("{foo}/{bar}")
public Response rest(@PathParam("foo") final String foo,
@PathParam("bar") final String bar) {
return Response.ok(foo + " " + bar).build();
}
Vous pouvez également utiliser des noms de méthode plus différents si vous rencontrez le cas où plusieurs méthodes surchargées ont la signature.
Une autre solution pour votre exemple particulier:
Supposons que:
/a
est pour la classe de ressources/b/c
et /b
sont les chemins des méthodescar un chemin complet ressemble à:
<protocol><Host><port><app><url-pattern><resource-path><method-path>
.
Utilisez le paramètre facultatif
@Path("/b{c : (/c)?}")
public Response searchNames(@PathParam("c") String val) {
...
}
L'exemple ci-dessus fonctionne pour tous les exemples comme:
/b
/b/
/b/c
/b/c/
mais lorsque c
est fourni, le val
est /c
(il a un /
avant).
Si vous souhaitez résoudre le problème ci-dessus (pour éviter Java), vous avez besoin de quelque chose de plus complexe:
@Path("/b{slash : (/)?}{c:((?<=/).*)?}")
qui renverra uniquement c
(pas /c
) pour le 3rd puce, mais pour le 4e puce, il renverra c/
qui doit être analysé en Java.
Mais pour votre cas ( "la méthode exécutée est la même"), ne vous inquiétez pas de l'analyse car vous n'avez pas d'actions différentes.