Possiamo avere più di un’annotazione @Path per lo stesso metodo REST

Possiamo avere più di un’annotazione @Path per lo stesso metodo REST, ovvero il metodo eseguito è lo stesso, ma viene eseguito all’accesso a più di un URL?

Ad esempio: voglio eseguire il metodo searchNames() su http://a/b/c e http://a/b .

Non è ansible avere più annotazioni @Path su un singolo metodo. Causa un errore di syntax “annotazione duplicata”.

Tuttavia, esistono diversi modi per mappare in modo efficace due percorsi a un metodo.

Espressioni regolari nell’annotazione @Path

L’annotazione @Path in JAX-RS accetta parametri, i cui valori possono essere limitati utilizzando le espressioni regolari.

Questa annotazione:

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

consentirebbe al metodo di essere raggiunto da richieste per /a/path1 e /a/path2 . Se hai bisogno di lavorare con sottotraccia, sfoglia le barre: {a:path1\\/subPath1|path2\\/subPath2}

Fornire risposte con un codice di stato di reindirizzamento

In alternativa, puoi impostare un reindirizzamento. Ecco un modo per farlo in Jersey (l’implementazione di riferimento di JAX-RS), definendo un’altra subresource. Questo è solo un esempio, se preferisci un diverso modo di gestire i reindirizzamenti, sentiti libero di usarlo.

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

Utilizzo di un filtro servlet per riscrivere gli URL

Se hai bisogno di questa funzionalità spesso, suggerisco di intercettare le richieste in arrivo usando un filtro servlet e di riscrivere i percorsi al volo. Questo dovrebbe aiutarti a mantenere tutti i reindirizzamenti in un unico posto. Idealmente, potresti usare una libreria pronta. UrlRewriteFilter può fare il trucco, a patto che tu stia bene con una licenza BSD (controlla i loro codici google site per i dettagli)

Un’altra opzione è gestirla con un proxy configurato di fronte all’app Java. È ansible configurare un server Apache per offrire regole di caching e riscrittura di base senza complicare il codice Java.

Come spiegato nella risposta di Tom , non è ansible utilizzare più di un’annotazione @Path su un singolo metodo, poiché si verificherà un error: duplicate annotation in fase di compilazione.

Penso che il modo più semplice per aggirare questo problema è utilizzare l’overloading dei metodi:

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

È anche ansible utilizzare nomi di metodi più diversi se si verifica il caso in cui più metodi con overload hanno la firma.

Un’altra soluzione per il tuo esempio particolare:

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

Supponiamo che:

  • /a è per la class di risorse
  • /b/c e /b sono i percorsi per i metodi

perché appare un percorso completo:

.

Usa parametro opzionale

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

L’esempio sopra funziona per tutti gli esempi come:

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

ma quando viene fornito c , val è /c (ha un / prima).

Se vuoi risolvere il problema precedente (per evitare l’analisi di Java), hai bisogno di qualcosa di più complesso:

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

che restituirà solo c (non /c ) per il 3 ° punto bullet, ma per il 4 ° punto bullet restituirà c/ che deve essere analizzato in Java.

Ma per il tuo caso ( "il metodo eseguito è lo stesso" ), non preoccuparti dell'analisi perché non hai azioni diverse.