因此,在仔细研究了Jax-RS的Optional@PathParam中的一些答案之后,问题是使用此方法
@Path("/myMethod{id: (/\d+)?}") public Response get(@PathParam("id") int id) {}使
/处于捕获组中。因此,当Jersey尝试解析时
/1,它将获得一个异常并发送404。我们可以使用String,但是随后它变得很丑陋,因为我们需要摆脱前导
/并 自行解析它。
@Path("/myMethod{id: (/\d+)?}") public Response get(@PathParam("id") String id) { id = id.replace("/", ""); int parsed = Integer.parseInt(id);}我想出的另一种解决方案(一种适用于OP的解决方案)是
/将数字与数字分隔成两个不同的路径表达式,这样
/就不会在实际的id中捕获前导并且不会导致解析失败
@Path("/method{noop: (/)?}{id: ((?<=/)\d+)?}")public Response get(@PathParam("id") int id) {}在
{noop: (/)?}捕获可选/。并且后面
{id:((?<=/)\d+)?}使用正号,表示\d+当且仅当前面有一个
/(
(?<=/))时才允许使用数字()。这是必需的,因为
/是可选的。如果我们不使用此断言,
/myMethod123则将被允许。
这是使用Jersey测试框架的完整测试案例
public class OptionalParamTest extends JerseyTest { @Path("optional") public static class Resource { @GET @Path("/method{noop: (/)?}{id: ((?<=/)\d+)?}") public String get(@PathParam("id") int id) { return String.valueOf(id); } } @Override public ResourceConfig configure() { return new ResourceConfig(Resource.class); } @Test public void should_return_id_1() { Response response = target("optional/method/1").request().get(); System.out.println("status=" + response.getStatus()); assertEquals("1", response.readEntity(String.class)); } @Test public void should_return_id_0_with_no_id() { Response response = target("optional/method").request().get(); assertEquals(200, response.getStatus()); assertEquals("0", response.readEntity(String.class)); } @Test public void should_return_404_with_numbers_and_no_slash() { Response response = target("optional/method12").request().get(); assertEquals(404, response.getStatus()); } @Test public void should_return_404_with_numbers_and_letters() { Response response = target("optional/method/12b").request().get(); assertEquals(404, response.getStatus()); } @Test public void should_return_404_with_only_letters() { Response response = target("optional/method/ab").request().get(); assertEquals(404, response.getStatus()); } }这是测试的依赖项
<dependency> <groupId>org.glassfish.jersey.test-framework.providers</groupId> <artifactId>jersey-test-framework-provider-grizzly2</artifactId> <version>${jersey2.version}</version> <scope>test</scope></dependency>编辑
对于测试,最好使用盒装
Integer而不是
int方法参数。使用前者,您将能够执行空检查,而不用接收
0原始图元的默认值。



