Ok. Then the solution is slightly uglier:
public class PersonResource {
private final String person;
private PersonResource(String person) {
this.person = person;
}
@GET
public String get() {
return "person";
}
}
public class LocationResource {
private final String person;
private LocationResource(String person) {
this.person = person;
}
@GET
public String get() {
return "location";
}
}
public class FriendsResource {
private final String person;
private FriendsResource(String person) {
this.person = person;
}
@GET
public String get() {
return "friends";
}
}
@Path("{person}")
public Object getPpl(@PathParam("person") String person,
@QueryParam("location") String location,
@QueryParam("friends") String friends) {
// you might want to handle location != null && friends != null
// if that state can occur.
if(location != null) {
return new LocationResource(person);
} else if (friends != null) {
return new FriendsResource(person);
} else {
return new PersonResource(person);
}
}
tested with following client calls:
WebResource webResource = resource();
webResource.addFilter(new LoggingFilter());
webResource.path("helloworld").path("person").get(String.class);
webResource.path("helloworld").path("person").queryParam("location",
"").get(String.class);
webResource.path("helloworld").path("person").queryParam("friends",
"").get(String.class);
hope it helps..
Pavel
On 11/16/11 3:20 PM, 王子剑 wrote:
> Hi Pavel
>
> Actually the return types are totally different, example:
>
> @Path("{people}")
> public People getPeople(@PathParam String people);
>
> @Path("{people}?location")
> public Location getLocation(@PathParam String people);
>
> @Path("{people}?friends")
> public List<People> getFriends(@PathParam String people);
>
> ......
>
> Jersey dispatch incoming request base on path rather on query
> parameters, but we can encode the expected query parameter to the path
> to implement it transparently.
>
> I write a ContainerRequestFilter to do this,
>
> public class SubResourceMatchableRequestFilter implements
> ContainerRequestFilter {
>
> @Override
> public ContainerRequest filter(ContainerRequest request) {
> final String subResource = getFirstSubResource(request);
> if (subResource == null) {
> return request;
> }
> return new AdaptingContainerRequest(request) {
> @Override
> public String getPath(boolean decode) {
> return new StringBuilder(super.getPath(decode))
> .append(decode ? "?" : "%3F")
> .append(subResource)
> .toString();
> }
> };
> }
>
> private String getFirstSubResource(ContainerRequest request) {
> String query = request.getRequestUri().getQuery();
> if (query == null) {
> return null;
> }
> int indexOfFirstAnd = query.indexOf("&");
> return indexOfFirstAnd == -1 ? query : query.substring(0,
> indexOfFirstAnd);
> }
> }
>
> The requirement can be archived, but I don`t know is there some hidden
> trouble?
>
> Looking forward to your reply, thanks.
>
> Regards,
> Zijian.
>
> 在 2011年11月16日 下午6:15,Pavel Bucek <pavel.bucek_at_oracle.com
> <mailto:pavel.bucek_at_oracle.com>>写 道:
>
> Yeah, you are right.
>
> It should be achievable by using reqexes, but I've tested this:
>
> @GET
> @Path("{people}")
> public String getPeople(@PathParam("people") String people,
> @QueryParam("location") String location) {
> if(location == null) {
> return location;
> } else {
> return people;
> }
> }
>
> and looks like it does what you need. location param here can be null
> ("?location" not present) or "" (empty string), thus you are able to
> decide what to return (you are using same return data type for both
> methods in you example so that shouldn't be a problem..
>
> Let me know if this works for you.
>
> Regards,
> Pavel
>
>
> On 11/16/11 2:39 AM, 王子剑 wrote:
> > Hi Pavel
> >
> > Thank you for your kind reply.
> >
> > The code: webResource.path("test?location").get(String.class); will
> > encode character *?* to *%3F*(url encode), that means the
> request url
> > will be *http://test.com/test%3Flocation* instead of
> > *http://test.com/test?location*.
> >
> > If someone use unencoded url like *http://test.com/test?location*,
> > Jersey will return 405 'MethodNotAllowed' response.
> >
> > Best regards.
> >
> > Zijian
> >
> > 2011/11/15 Pavel Bucek <pavel.bucek_at_oracle.com
> <mailto:pavel.bucek_at_oracle.com>
> > <mailto:pavel.bucek_at_oracle.com <mailto:pavel.bucek_at_oracle.com>>>
> >
> > Hi 王子剑,
> >
> > please use users_at_jersey.java.net <mailto:users_at_jersey.java.net>
> <mailto:users_at_jersey.java.net <mailto:users_at_jersey.java.net>>
> > mailing list, this one is for mailing list administration only.
> >
> > And about your issue - it can be achieved, you need to exclude
> > requests containing question mark from first method. See following:
> >
> > @GET
> > @Path("{people:[^\\?]*}")
> > public String getPeople(@PathParam("people") String people) {
> > return people;
> >
> > }
> >
> > @GET
> > @Path("{people}?location")
> > public String getLocation(@PathParam("people") String people) {
> > return "location:" + people;
> > }
> >
> > I verified this with following requests:
> >
> > responseMsg = webResource.path("test").get(String.class); //
> > matches getPeople
> > responseMsg = webResource.path("test?location").get(String.class);
> > // matches getLocation
> >
> > Regards,
> > Pavel
> >
> >
> >
> >
> >
> > On 11/15/11 11:10 AM, 王子剑 wrote:
> >> Hello All
> >>
> >> I am handling a legacy system and I cannot process the request by
> >> Jersey gracefully.
> >>
> >> API:
> >>
> >> *GET : http://test.com/{people} <http://test.com/%7Bpeople%7D>
> >> <http://test.com/%7Bpeople%7D> * Get people information
> >>
> >> *GET : http://test.com/{people}?location
> <http://test.com/%7Bpeople%7D?location>
> >> <http://test.com/%7Bpeople%7D?location>* Get people location.
> >>
> >>
> >>
> >> Code
> >>
> >> *_at_GET*
> >> *_at_Path("{people}")*
> >> *public People getPeopleInformation(String people);*
> >> *
> >> *
> >> *_at_GET*
> >> *_at_Path("{people}?location")*
> >> *public People getPeopleLocation(String people);*
> >> *
> >> *
> >>
> >> Jersey will not invoke the second method *getPeopleLocation *when
> >> the client request url: *http://test.com/{people}?location
> <http://test.com/%7Bpeople%7D?location>
> >> <http://test.com/%7Bpeople%7D?location>*, it always dispatch the
> >> incoming request which end with '?location' to the first method
> >> '*getPeopleInformation*'.
> >>
> >> Is there some way to let Jersey to dispatch request based on
> >> query parameters like this situation?
> >> *
> >> *
> >> *
> >> *
> >
> >
>
>