Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we have more than one @Path annotation for same REST method [duplicate]

Can we have more than one @Path annotation for same REST method i.e. the method executed is the same, but it is executed on accessing more than one URL?

E.g.: I want to run the searchNames() method on both http://a/b/c and http://a/b.

like image 570
Unreal user Avatar asked Jun 08 '13 13:06

Unreal user


People also ask

What is the use of @path annotation?

The @Path annotation is used to specify the URI through which a resource and an API can be accessed. Resource in this case is the REST Web service itself. Thus this annotation is present at the class level as well as the method level. It is mandatory to annotate a REST Web resource class with the @Path annotation.

What is @path annotation in Java?

The @Path annotation identifies the URI path template to which the resource responds and is specified at the class or method level of a resource.

What does annotation @PathParam for resource mapping?

The @PathParam annotation is a type of parameter that you can extract for use in your resource class. URI path parameters are extracted from the request URI, and the parameter names correspond to the URI path template variable names specified in the @Path class-level annotation.

What are REST annotations?

Annotations are like meta-tags that you can add to the code and apply to package declarations, type declarations, constructors, methods, fields, parameters, and variables.


2 Answers

You can't have mutliple @Path annotations on a single method. It causes a "duplicate annotation" syntax error.

However, there's a number of ways you can effectively map two paths to a method.

Regular expressions in @Path annotation

The @Path annotation in JAX-RS accepts parameters, whose values can be restricted using regular expressions.

This annotation:

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

would enable the method to be reached by requests for both /a/path1 and /a/path2. If you need to work with subpaths, escape slashes: {a:path1\\/subPath1|path2\\/subPath2}

Serving responses with a redirection status code

Alternatively, you could set up a redirection. Here's a way to do it in Jersey (the reference implementation of JAX-RS), by defining another subresource. This is just an example, if you prefer a different way of handling redirections, feel free to use it.

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

Using a servlet filter to rewrite URLs

If you're going to need such functionality often, I suggest intercepting the incoming requests using a servlet filter and rewriting the paths on the fly. This should help you keep all redirections in one place. Ideally, you could use a ready library. UrlRewriteFilter can do the trick, as long as you're fine with a BSD license (check out their google code site for details)

Another option is to handle this with a proxy set up in front of your Java app. You can set up an Apache server to offer basic caching and rewrite rules without complicating your Java code.

like image 69
toniedzwiedz Avatar answered Sep 30 '22 04:09

toniedzwiedz


As explained in Tom's answer, you can not use more than one @Path annotation on a single method, because you will run into error: duplicate annotation at compile time.

I think the simplest way to get around this is to use method overloading:

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

You could also use more different method names if you run into the case where multiple overloaded methods have the signature.

like image 30
yegeniy Avatar answered Sep 30 '22 04:09

yegeniy