Podemos ter mais de uma anotação @Path para o mesmo método REST

Podemos ter mais de uma anotação @Path para o mesmo método REST, ou seja, o método executado é o mesmo, mas é executado ao acessar mais de um URL?

Por exemplo: eu quero executar o método searchNames() em http://a/b/c http://a/b .

Você não pode ter annotations @Path múltiplas em um único método. Isso causa um erro de syntax de “anotação duplicada”.

No entanto, há várias maneiras de mapear efetivamente dois caminhos para um método.

Expressões regulares na anotação @Path

A anotação @Path no JAX-RS aceita parâmetros, cujos valores podem ser restringidos usando expressões regulares.

Esta anotação:

@Path("a/{parameter: path1|path2}")

permitiria que o método fosse alcançado por pedidos para ambos /a/path1 e /a/path2 . Se você precisar trabalhar com subcaminhos, escape de barras: {a:path1\\/subPath1|path2\\/subPath2}

Servindo respostas com um código de status de redirecionamento

Como alternativa, você pode configurar um redirecionamento. Aqui está uma maneira de fazer isso em Jersey (a implementação de referência do JAX-RS), definindo outro sub-recurso. Este é apenas um exemplo, se você preferir uma maneira diferente de lidar com os redirecionamentos, sinta-se à vontade para usá-lo.

 @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(); } } 

Usando um filtro de servlet para rewrite URLs

Se você precisar dessa funcionalidade com frequência, sugiro interceptar as solicitações recebidas usando um filtro de servlet e reescrevendo os caminhos na hora. Isso deve ajudá-lo a manter todos os redirecionamentos em um só lugar. Idealmente, você poderia usar uma biblioteca pronta. UrlRewriteFilter pode fazer o truque, contanto que você esteja bem com uma licença BSD (confira o site do google code para detalhes)

Outra opção é lidar com isso com um proxy configurado na frente do seu aplicativo Java. Você pode configurar um servidor Apache para oferecer armazenamento em cache básico e rewrite regras sem complicar seu código Java.

Como explicado na resposta de Tom , você não pode usar mais de uma anotação @Path em um único método, porque você vai encontrar error: duplicate annotation em tempo de compilation.

Eu acho que a maneira mais simples de contornar isso é usar sobrecarga de método:

 @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(); } 

Você também pode usar nomes de método mais diferentes se for executado no caso em que vários methods sobrecarregados possuem a assinatura.

Outra solução para o seu exemplo específico:

  • http: // a / b / c
  • http: // a / b

Vamos supor que:

  • /a é para a class de recurso
  • /b/c e /b são os caminhos para os methods

porque um caminho completo se parece com:

.

Use o parâmetro opcional

 @Path("/b{c : (/c)?}") public Response searchNames(@PathParam("c") String val) { ... } 

O exemplo acima funciona para todos os exemplos como:

  • /b
  • /b/
  • /b/c
  • /b/c/

mas quando c é fornecido, o val é /c (tem um / antes).

Se você quiser corrigir o problema acima (para evitar a análise de Java), você precisa de algo mais complexo:

 @Path("/b{slash : (/)?}{c:((?<=/).*)?}") 

que retornará apenas c (não /c ) para o ponto, mas para o ponto ele retornará c/ que deve ser analisado em Java.

Mas para o seu caso ( "o método executado é o mesmo" ), não se preocupe com a análise porque você não tem ações diferentes.