@QueryParam 如何将没有值的参数转换为布尔值 "false"?
How can @QueryParam translate a parameter without value to boolean "false"?
我想使用像 http://www.example.com/rest/foo?bar
这样的 URL,其中 bar
查询参数没有值,它的存在本身应该表示变量是否 true
或 false
。
目前,缺失值假定为 ""
(空)并传递给 new Boolean()
,后者将其视为 false
。
有没有比声明参数为String并自己转换更优雅的定义方式?
喜欢例如class javax.rs.BooleanFlag
或类似的?
您可以尝试以下方法:
@GET
@Path("/some-path")
public Response myMethod(@Context HttpServletRequest request) {
boolean isParameterPresent = request.getParameterMap().contains("bar");
...
}
但是 中显示的解决方案是实现它的最聪明的方法。
注意: 看到 ,我会选择 his/her 解决方案。我要留下这个答案,因为这里还有一些有用的信息。
Is there a more elegant way of defining it than declaring the parameter to be String and converting it myself? Like e.g. a class javax.rs.BooleanFlag
or similar?
没有这样的类型 (BooleanFlag
),如果您查看 javadoc for @QueryParam,您会看到一个选项列表,说明我们如何创建自定义类型以使用 @QueryParam
值(在大多数情况下,其他 @XxxParam
也是如此)
- Have a constructor that accepts a single String argument
- Have a
static
method named valueOf
or fromString
that accepts a single String argument (see, for example, Integer.valueOf(String)
)
- Have a registered implementation of
ParamConverterProvider
JAX-RS extension SPI that returns a ParamConverter
instance capable of a "from string" conversion for the type.
所以从第一个选项开始,理论上你应该可以做类似
的事情
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)
,但这并不比仅使用字符串并检查字符串是否为空更好。这不是漂亮。
所以最后一个选项是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 <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; }
};
}
}
只需确保提供商已注册。在我看来,这是一个非常干净的解决方案。
我知道这是一个老问题,但我遇到了同样的麻烦。
为了解决我的问题,我使用了注解@DefaultValue :
@GET
@Path("/path")
public Response myMethod(@DefaultValue("true") @QueryParam("foo") boolean foo) {
if (foo) {
...
}
}
因此,当请求包含参数 foo
时,布尔值将为 false,否则为 true。它显示了与现实相反的情况,但如果您意识到这一点,使用起来会非常简单。
我想使用像 http://www.example.com/rest/foo?bar
这样的 URL,其中 bar
查询参数没有值,它的存在本身应该表示变量是否 true
或 false
。
目前,缺失值假定为 ""
(空)并传递给 new Boolean()
,后者将其视为 false
。
有没有比声明参数为String并自己转换更优雅的定义方式?
喜欢例如class javax.rs.BooleanFlag
或类似的?
您可以尝试以下方法:
@GET
@Path("/some-path")
public Response myMethod(@Context HttpServletRequest request) {
boolean isParameterPresent = request.getParameterMap().contains("bar");
...
}
但是
注意: 看到
Is there a more elegant way of defining it than declaring the parameter to be String and converting it myself? Like e.g. a class
javax.rs.BooleanFlag
or similar?
没有这样的类型 (BooleanFlag
),如果您查看 javadoc for @QueryParam,您会看到一个选项列表,说明我们如何创建自定义类型以使用 @QueryParam
值(在大多数情况下,其他 @XxxParam
也是如此)
- Have a constructor that accepts a single String argument
- Have a
static
method namedvalueOf
orfromString
that accepts a single String argument (see, for example,Integer.valueOf(String)
)- Have a registered implementation of
ParamConverterProvider
JAX-RS extension SPI that returns aParamConverter
instance capable of a "from string" conversion for the type.
所以从第一个选项开始,理论上你应该可以做类似
的事情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)
,但这并不比仅使用字符串并检查字符串是否为空更好。这不是漂亮。
所以最后一个选项是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 <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; }
};
}
}
只需确保提供商已注册。在我看来,这是一个非常干净的解决方案。
我知道这是一个老问题,但我遇到了同样的麻烦。
为了解决我的问题,我使用了注解@DefaultValue :
@GET
@Path("/path")
public Response myMethod(@DefaultValue("true") @QueryParam("foo") boolean foo) {
if (foo) {
...
}
}
因此,当请求包含参数 foo
时,布尔值将为 false,否则为 true。它显示了与现实相反的情况,但如果您意识到这一点,使用起来会非常简单。