Java:Enum不区分大小写的Jersey查询参数绑定
我试图覆盖/实现中的所有属性,但Jersey绑定似乎区分大小写:Java:Enum不区分大小写的Jersey查询参数绑定,java,spring,rest,jakarta-ee,jersey,Java,Spring,Rest,Jakarta Ee,Jersey,我试图覆盖/实现中的所有属性,但Jersey绑定似乎区分大小写: 是原始类型 具有接受单个字符串参数的构造函数 有一个名为valueOf或fromString的静态方法,该方法接受单个字符串参数(例如,请参见Integer.valueOf(String)) 是列表、集合或分类集合,其中T满足上述2或3。生成的集合是只读的 如何使enum的Jersey绑定不区分大小写 编辑: 代码如下: 枚举: public enum Color { GREEN, BLUE; pub
public enum Color {
GREEN,
BLUE;
public Color fromString(String param) {
String toUpper = param.toUpperCase();
try {
return valueOf(toUpper);
} catch (Exception e) {
return null;
}
}
}
Bean参数:
public class FooQueryParam {
@QueryParam(value = "color")
private Color color;
public Color getColor() {
return color;
}
public void setStatus(Color Color) {
this.color = color;
}
}
资源:
public Response get(@BeanParam FooQueryParam fooQueryParam) {
//...
}
如果你做得对,那应该不会有问题。例如,在案例3中,使用
fromString
public static enum Color {
RED, GREEN, BLUE;
public static Color fromString(String param) {
String toUpper = param.toUpperCase();
try {
return valueOf(toUpper);
} catch (Exception e) {
// default behavior is to send 404 on error.
// do something else if you want
throw new WebApplicationException(400);
}
}
}
每个枚举已经有一个静态的valueOf
方法,该方法尝试精确匹配枚举值,因此我们通过定义fromString
来覆盖此行为。我们首先调用toUpperCase()
,然后调用valueOf
,因为它正在查找大写字母。如果有任何失败,例如错误的枚举值,我们将发送一个400。您可以发送其他邮件或使用普通的404。由你决定
我已经这样做了,它不起作用
这是一个完整的测试用例
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class EnumTest extends JerseyTest {
public static enum Color {
RED, GREEN, BLUE;
public static Color fromString(String param) {
String toUpper = param.toUpperCase();
try {
return valueOf(toUpper);
} catch (Exception e) {
// default behavior is to send 404 on error.
// do something else if you want
throw new WebApplicationException(400);
}
}
}
@Path("enum")
public static class ColorResource {
@GET
public String color(@QueryParam("color") Color color) {
return color.toString();
}
}
@Override
public ResourceConfig configure() {
return new ResourceConfig(ColorResource.class);
}
@Test
public void doit() {
Response response = target("enum").queryParam("color", "blue").request().get();
assertEquals(200, response.getStatus());
assertEquals("BLUE", response.readEntity(String.class));
response.close();
response = target("enum").queryParam("color", "gReEn").request().get();
assertEquals(200, response.getStatus());
assertEquals("GREEN", response.readEntity(String.class));
response.close();
response = target("enum").queryParam("color", "RED").request().get();
assertEquals(200, response.getStatus());
assertEquals("RED", response.readEntity(String.class));
response.close();
response = target("enum").queryParam("color", "orange").request().get();
assertEquals(400, response.getStatus());
response.close();
}
}
使用此依赖项
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>2.19</version>
<scope>test</scope>
</dependency>
唯一失败的是错误情况,我发送了一个坏颜色。似乎
@BeanParam
的行为有所不同。而不是预期的400,而是500。其他区分大小写的问题很好“但Jersey绑定似乎不区分大小写”。。。“如何使enum的Jersey绑定不区分大小写”。。。那是哪一个呢?它似乎不区分大小写,所以如何使它如此???这是一个整洁的解决方案。唯一让我有点困惑的是,如果两者都已定义,您如何确定Jersey将调用fromString(String)
而不是valueOf(String)
?是否指定了此行为?@richersoon我恐怕唯一剩下的就是将该值映射为一个纯粹的字符串
,然后调用YourEnum.valueOf(input.toUpperCase())
@CostiCiudatu我猜它在算法中。我知道valueOf
和fromString
有不同的提供者。在不查看任何源代码的情况下,我猜首先使用的是fromString
提供程序。我从未遇到过使用枚举的问题。顺便说一句,我认为这种行为在任何地方都没有记录。我添加了我的代码。。静态是否与此有关?@CostiCiudatu只是为了确认,我刚刚检查了源代码,并且,ParamConverter
s是按照它们在数组中的顺序选择的,如图所示。如您所见,TypeFromStringEnum
位于TypeValueOf
之前。如果这不是枚举,则TypeValueOf
位于“plain”TypeFromString
提供程序之前
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class EnumTest extends JerseyTest {
public static enum Color {
RED, GREEN, BLUE;
public static Color fromString(String param) {
String toUpper = param.toUpperCase();
System.out.println("--- toUpper " + toUpper + "---");
try {
return valueOf(toUpper);
} catch (Exception e) {
System.out.println(" --- ERROR ---");
// default behavior is to send 404 on error.
// do something else if you want
throw new WebApplicationException(400);
}
}
}
public static class FooQueryParam {
@QueryParam("color")
private Color color;
public Color getColor() { return color; }
public void setColor(Color color) { this.color = color; }
}
@Path("enum")
public static class ColorResource {
@GET
public String color(@BeanParam FooQueryParam foo) {
return foo.getColor().toString();
}
}
@Override
public ResourceConfig configure() {
return new ResourceConfig(ColorResource.class);
}
@Test
public void doit() {
Response response = target("enum").queryParam("color", "blue").request().get();
assertEquals(200, response.getStatus());
assertEquals("BLUE", response.readEntity(String.class));
response.close();
response = target("enum").queryParam("color", "gReEn").request().get();
assertEquals(200, response.getStatus());
assertEquals("GREEN", response.readEntity(String.class));
response.close();
response = target("enum").queryParam("color", "RED").request().get();
assertEquals(200, response.getStatus());
assertEquals("RED", response.readEntity(String.class));
response.close();
response = target("enum").queryParam("color", "orange").request().get();
assertEquals(400, response.getStatus());
response.close();
}
}