Jersey Client / JAX-RS and optional (not default) @QueryParam (client side)

前端 未结 2 997
醉梦人生
醉梦人生 2021-02-07 06:47

I have a RESTful API who\'s document says that a certain query parameter is optional, and does not supply a default argument. So, I can either supply the value or not send it i

相关标签:
2条回答
  • 2021-02-07 07:22

    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);
    
    0 讨论(0)
  • 2021-02-07 07:37

    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
      }
      ...
    }
    
    0 讨论(0)
提交回复
热议问题