@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参数的构造函数
- 有一个名为
valueOf
或fromString
的static
方法接受单个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。 使用fromString
和valueOf
进行测试,结果相同。 我们可以检查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。 它显示了与现实相反的情况,但如果你意识到它,它的使用起来非常简单。