Jersey Client / JAX-RS and optional (not default) @QueryParam (client side)
You can inject a UriInfo
instance (or something else like HttpServletRequest
) into your method, and get whatever data you want off of it.
For example
@Path("/endpoint")
@GET
public Response getEndpoint(@Context UriInfo info, @QueryParam("queryA") String queryA) {
String queryB = info.getQueryParameters().getFirst("queryB");
if (null != queryB) {
// do something with it
}
...
}
The interface was right all along
I can't believe it was this easy:
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
@Path("/service")
@Produces("application/json")
public interface ServiceInterface {
@Path("/endpoint")
@GET
public Response getEndpoint(
@QueryParam("queryA") String first,
@QueryParam("queryB") String second);
}
Notice anything different than the questions interface?? Nope. That's because that is the answer!
Don't use @DefaultValue for optional parameters
If you want to default a parameter to a specific value, you use the @DefaultValue
annotation in the parameter:
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
@Path("/service")
@Produces("application/json")
public interface ServiceInterface {
@Path("/endpoint")
@GET
public Response getEndpoint(
@QueryParam("queryA") String first,
@QueryParam("queryB") @DefaultValue("default") String second);
}
Pass null
to the @QueryParam
you don't want
If you want to make the @QueryParam
optional, you do not apply the @DefaultValue
annotation. To pass a value with the query parameter, just pass in the value normally. If you would like the query parameter to not show up at all, just pass null
!
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
@Path("/service")
@Produces("application/json")
public interface ServiceInterface {
@Path("/endpoint")
@GET
public Response getEndpoint(
@QueryParam("queryA") String first,
// Pass null to this parameter to not put it in the GET request
@QueryParam("queryB") String second);
}
So calling ServiceInterface.getEndpoint("firstQueryParam", "secondQueryParam");
calls:
http://targethost.com/service/endpoint?queryA=firstQueryParam&queryB=secondQueryParam
and calling ServiceInterface.getEndpoint("firstQueryParam", null);
calls:
http://targethost.com/service/endpoint?queryA=firstQueryParam
And walla! No second query parameter! :)
Note on primitive values
If your API takes primitive values (like int
, float
, boolean
, etc), then use the object wrapper class (Autoboxing) for that primitive (like Integer
, Float
, Boolean
, etc). Then, you can pass null
to the method:
public Response getEndpoint(@QueryParam("queryA") Boolean first);