2015-05-10 12 views
11

Mam interfejs API RESTful API, który mówi, że pewien parametr zapytania jest opcjonalny i nie podaje domyślnego argumentu. Mogę więc podać wartość lub nie wysłać jej w żądaniu GET jako parametru.Klient sieci Jersey/JAX-RS i opcjonalny (nie domyślny) @QueryParam (strona klienta)

przykład:

  • queryA jest wymagane
  • queryB jest opcjonalnie (można wysłać GET bez niego)

ta powinna działać:

http://www.example.com/service/endpoint?queryA=foo&queryB=bar 

T Jego powinny również działać:

http://www.example.com/service/endpoint?queryA=foo 

Jak zrobić interfejs klienta dla Jersey-Proxy że można to zrobić ?? Nie mam kodu po stronie serwera do interfejsu, więc używam org.glassfish.jersey.client.proxy.WebResourceFactory przez Jersey-Proxy, aby wygenerować klienta do interakcji z interfejsem API serwera.

interfejs próbki:

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); 

} 

wiem, że mogę zrobić inną metodę:

@Path("/endpoint") 
    @GET 
    public Response getEndpoint(
      @QueryParam("queryA") String first); 

Ale co się dzieje, gdy masz wiele pól opcjonalnych ?? Nie chcę robić ich wszystkich możliwych mutacji!

+0

To może odpowiedzieć na pytanie: http://stackoverflow.com/questions/13968261/required-queryparam-in-jax-rs-and-what-to-do-in-their-absence – quintin

+0

Że jest po stronie serwera, a nie po stronie klienta. – justderb

Odpowiedz

20

Interfejs miał rację

Nie mogę uwierzyć, że to było to łatwe:

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); 

} 

Wskazówka niczego innego niż interfejs pytania ?? Nie. To dlatego, że to jest odpowiedź!


Nie używaj @DefaultValue

Jeśli chcesz domyślnie parametr do określonej wartości, należy użyć @DefaultValue adnotacji w parametrze:

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); 

} 

przepustkę null do @QueryParam nie chcesz

Jeśli chcesz, aby opcja @QueryParam była opcjonalna, nie stosuj adnotacji @DefaultValue. Aby przekazać wartość za pomocą parametru zapytania, wystarczy podać wartość normalnie. Jeśli chcesz, aby parametr zapytania w ogóle się nie pojawiał, wystarczy podać 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); 

} 

Więc zawijające ServiceInterface.getEndpoint("firstQueryParam", "secondQueryParam"); rozmowy:

http://targethost.com/service/endpoint?queryA=firstQueryParam&queryB=secondQueryParam 

i wzywaj ServiceInterface.getEndpoint("firstQueryParam", null); rozmowy:

http://targethost.com/service/endpoint?queryA=firstQueryParam 

I Walla! Brak drugiego parametru zapytania! :)

+1

co z liczbami zamiast ciągów? Nie ma możliwości użycia wartości NULL, więc musisz sprawdzić wartość. – jlanza

+0

Uważam, że należy to zrobić, używając typów automatycznych skrzynek: 'Boolean',' Integer', etc .... – justderb

1

Możesz wstrzyknąć instancję UriInfo (lub coś innego, jak HttpServletRequest) do swojej metody i uzyskać dowolne dane poza nią.

Na przykład

@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

Czy to działa z 'WebResourceFactory' z Jersey z czubkiem głowy? Zajmę się sprawdzaniem, czy mogę to zrobić ... – justderb

+0

Wspomniałeś o kliencie z Jersey, ale o ile mogę powiedzieć, że twój przykład to definicja punktu końcowego JAX-RS po stronie serwera ... – Alex

+0

Definicja jest dla klienta -side, ponieważ nie mam kodu po stronie serwera. – justderb