Reputation: 234
I have two REST URLs like:
http://myschool/student/jack //get student information.
http://myschool/student/jack?books //get student books.
Code:
@Path("student")
public class StudentResource {
@GET
@Path("{name}")
public Response getInformation(@PathParam("name") String name) {
return Response.ok(loadStudentInformation(name));
}
@GET
@Path("{name}?books") //ineffective expression
public Response getBooks(@PathParam("name") String name) {
return Response.ok(loadStudentBooks(name));
}
Jersey cannot process the second url 'http://myschool/student/jack?books', it always dispatch the incoming request which end with '?books' to the first method 'getInformation'.
I try to use regular expression like this:
@GET
@Path("{name : .*(\\?books$)}") //ineffective expression
public Response getBooks(@PathParam("name") String studentName) {
The regular expression is ineffective too, can someone please help me figure out how to implement this.
Thanks.
Upvotes: 1
Views: 4213
Reputation: 7989
If you really need to use question mark to separate {name} and books, you can do it as follows:
@GET
@Path("{name}")
public Response getInformation(@PathParam("name") String name, @QueryParam("books") String books) {
if (books != null) {
// "books" was included after the question mark
return getBooks(name);
} else {
// "books" was not included after the question mark
return Response.ok(loadStudentInformation(name));
}
}
public Response getBooks(String name) {
return Response.ok(loadStudentBooks(name));
}
UPDATE: Also, if you are using a question mark where slash would be more appropriate (as according to the spec, question mark starts the query parameters section), as another alternative you can consider writing a ContainerRequestFilter that replaces question mark in the request by slash - this will allow you to design your resources as the other answer suggests without breaking the API compatibility.
The filter can be as simple as this:
public class QueryParamToPathSegmentFilter implements ContainerRequestFilter {
@Override
public ContainerRequest filter(ContainerRequest request) {
String requestUri = request.getRequestUri().toString();
requestUri = requestUri.replace('?', '/');
request.setUris(request.getBaseUri(), UriBuilder.fromUri(requestUri).build());
return request;
}
}
Depending on how your URI's look like - you can make it more sophisticated. Here is more on how you can register filters in your application: http://jersey.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/api/container/filter/package-summary.html
Upvotes: 3
Reputation: 14053
You could just set the path to:
@Path("{name}/books")
instead of:
@Path("{name}?books")
and then you would just get the list of books at that url:
http://myschool/student/jack/books //get student books.
Question mark in a URL usually means that you want to pass parameters to a service (in which case you'd want to use QueryParam
), but I don't think this is what it is about here, you just want to create a different service.
Upvotes: 0