@QueryParam如何将没有值的参数转换为布尔值“false”?

我想使用像http://www.example.com/rest/foo?bar这样的http://www.example.com/rest/foo?bar ,其中bar查询参数没有任何值,并且它的存在应该表示变量是true还是false

目前,缺失值假定为"" (空)并传递给new Boolean() ,后者将其视为false

是否有更优雅的方式来定义它,而不是将参数声明为String并自己转换它?

比如像一个类javax.rs.BooleanFlag或类似的?

您可以尝试以下方法:

 @GET @Path("/some-path") public Response myMethod(@Context HttpServletRequest request) { boolean isParameterPresent = request.getParameterMap().contains("bar"); ... } 

但peeskillet回答中显示的解决方案是实现它的最聪明的方法。

注意:看到Phoste的答案后 ,我会选择他/她的解决方案。 我正在离开这个答案,因为这里仍然有一些有用的信息。

是否有更优雅的方式来定义它,而不是将参数声明为String并自己转换它? 比如像一个类javax.rs.BooleanFlag或类似的?

没有这样的类型( BooleanFlag ),如果你看一下@QueryParam的javadoc ,你会看到一个选项列表,我们可以创建一个自定义类型来使用@QueryParam值(大部分同样适用于其他类型) @XxxParam也)

  • 有一个接受单个String参数的构造函数
  • 有一个名为valueOffromStringstatic方法接受单个String参数(例如,参见Integer.valueOf(String)
  • 有一个ParamConverterProvider JAX-RS扩展SPI的注册实现,它返回一个ParamConverter实例,该实例能够为该类型进行“from string”转换。

所以从理论上讲,从第一个选项开始,你应该可以做类似的事情

 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"; } } 

现在这在查询标志存在时有效。 但是当它不是时,它就像任何其他非原始类型一样; 它是空的。 因此,对bar.isPresent的调用给出了NPE。 使用fromStringvalueOf进行测试,结果相同。 我们可以检查if (bar == null) ,但仅仅使用String并检查String是否为null并不是更好。 它不漂亮

所以最后一个选项是ParamConverterProvider 。 哪个确实有效。 以下是实施。

 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  ParamConverter getConverter( Class rawType, Type genericType, Annotation[] annotations) { if (rawType != Flag.class) { return null; } return new ParamConverter() { @Override public T fromString(String value) { return (T)new Flag(value); } @Override public String toString(T value) { return null; } }; } } 

只需确保提供商已注册。 在我看来,这是一个非常干净的解决方案。

我知道这是一个老问题,但我遇到了同样的麻烦。

为了解决我的问题,我使用了Annotation @DefaultValue:

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

因此,当请求包含参数foo ,布尔值将为false,否则将为true。 它显示了与现实相反的情况,但如果你意识到它,它的使用起来非常简单。