2015-10-21 12 views
7

Mi piacerebbe utilizzare un URL come http://www.example.com/rest/foo?bar dove il parametro di query bar non ha valore e la sua presenza da sola dovrebbe indicare se una variabile è true o false.Come può @QueryParam tradurre un parametro senza valore in booleano "falso"?

Attualmente il valore mancante si presume essere "" (vuoto) e passato a new Boolean() che lo considera come false.

C'è un modo più elegante di definirlo che dichiarare il parametro come String e convertirlo da solo?

Come per es. una classe javax.rs.BooleanFlag o simile?

+0

Se si elimina una risorsa, perché non si utilizza il metodo 'DELETE'? –

+0

Nel mio caso sono stato generato un dato statistico e talvolta dovrei eliminare i record che sono stati utilizzati per questa statistica in seguito. Si prega di ignorare il nome del parametro, è irrilevante per la mia domanda e lo modifico ora! :) – lathspell

risposta

5

si potrebbe provare la seguente:

@GET 
@Path("/some-path") 
public Response myMethod(@Context HttpServletRequest request) { 

    boolean isParameterPresent = request.getParameterMap().contains("bar"); 

    ... 
} 

Ma le soluzioni indicate in peeskillet's answer sono i modi più intelligenti per realizzarla.

+0

Funziona, grazie. È solo un peccato che la firma del metodo ora manchi completamente di informazioni su questo parametro. (Non che io sia un grande amico della generazione automatica di WADL ma a volte è bello ...) – lathspell

8

C'è un modo più elegante di definirlo che dichiarare il parametro come String e convertirlo da solo? Come per es. una classe javax.rs.BooleanFlag o simile?

No tale tipo (BooleanFlag), se si guarda al javadoc for @QueryParam, vedrete una lista di opzioni per come possiamo creare un tipo personalizzato da utilizzare un valore @QueryParam (per la maggior parte lo stesso vale per altri @XxxParam s anche)

  • avere un costruttore che accetta un singolo argomento stringa
  • avere un metodo chiamato staticvalueOf o fromString che accetta un singolo argomento stringa (vedi, f o esempio, Integer.valueOf(String))
  • Avere un'implementazione registrata di ParamConverterProvider SPI estensione JAX-RS che restituisce un'istanza ParamConverter in grado di una conversione "da stringa" per il tipo.

Così dalla prima opzione, in teoria, si dovrebbe essere in grado di fare qualcosa di simile

public class Flag { 

    private final boolean isPresent; 
    public Flag(String param) { isPresent = param != null; } 
    public boolean isPresent() { return isPresent; } 
} 
@GET 
public String get(@QueryParam("bar") Flag bar) { 
    if (bar.isPresent()) { 
     return "bar is present"; 
    } else { 
     return "bar is not present"; 
    } 
} 

Ora, questo funziona quando la bandiera query è presente. Ma quando non lo è, agisce come qualsiasi altro tipo non primitivo; è nulla. Quindi la chiamata a bar.isPresent fornisce un NPE. Testato con un fromString e valueOf con lo stesso risultato. Noi è possibile controllare if (bar == null), ma non è meglio usare semplicemente una stringa e controllare se la stringa è nulla. Non è piuttosto.

Quindi l'ultima opzione è ParamConverterProvider. Che funziona davvero. Di seguito è l'implementazione.

import java.lang.annotation.Annotation; 
import java.lang.reflect.Type; 
import javax.ws.rs.ext.ParamConverter; 
import javax.ws.rs.ext.ParamConverterProvider; 
import javax.ws.rs.ext.Provider; 

@Provider 
public class FlagParamConverterProvider implements ParamConverterProvider { 

    @Override 
    public <T> ParamConverter<T> getConverter(
      Class<T> rawType, Type genericType, Annotation[] annotations) { 
     if (rawType != Flag.class) { 
      return null; 
     } 

     return new ParamConverter<T>() { 

      @Override 
      public T fromString(String value) { 
       return (T)new Flag(value); 
      } 

      @Override 
      public String toString(T value) { return null; } 
     }; 
    } 
} 

Basta assicurarsi che il provider sia registrato.È una soluzione abbastanza pulita secondo me.

+0

Se non fornisco il parametro 'bar' sulla mia classe, l'oggetto' Flag' è ancora 'null', quindi I ancora bisogno di controllare 'bar == null? false: bar.isPresent() ' –

5

So che è una vecchia domanda ma ho avuto lo stesso problema.

per risolvere il mio problema, ho usato il @DefaultValue della nota:

@GET 
@Path("/path") 
public Response myMethod(@DefaultValue("true") @QueryParam("foo") boolean foo) { 
    if (foo) { 
     ... 
    } 
} 

Così, quando la richiesta contiene il parametro foo il valore booleano sarà falso e se non sarà vero. Mostra il contrario della realtà, ma se ne sei consapevole, è abbastanza semplice da usare.

Problemi correlati