Jor*_*GRC 9 java rest jersey jersey-2.0
我正在玩Jersey 2.21,我想知道是否有可能有一个"可选"的参数,它可以或不存在于对服务器的请求中.
我想成功访问这两种方法:
http://localhost:8080/my_domain/rest/api/myMethod/1
http://localhost:8080/my_domain/rest/api/myMethod
Run Code Online (Sandbox Code Playgroud)
如您所见,我正在尝试使integer(id)参数成为可选参数.
我已声明myMethod如下:
@GET
@Path("myMethod/{id}")
@Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
public String myMethod(@PathParam("id") Integer id, @Context HttpHeaders hh)
Run Code Online (Sandbox Code Playgroud)
这有效:
http://localhost:8080/my_domain/rest/api/myMethod/1
Run Code Online (Sandbox Code Playgroud)
这也有效:
http://localhost:8080/my_domain/rest/api/myMethod/
Run Code Online (Sandbox Code Playgroud)
但这不起作用,我不明白为什么.它抛出一个404 Not Found错误:
http://localhost:8080/my_domain/rest/api/myMethod
Run Code Online (Sandbox Code Playgroud)
你能指出我正确的方向来解决这个问题吗?我不喜欢斜线在所有REST方法调用中都是强制性的,并且如果可能的话想要压缩它.
Pau*_*tha 10
所以在一些涉及Jax-RS的Optional @PathParam中的一些答案之后,问题是使用这个
@Path("/myMethod{id: (/\\d+)?}")
public Response get(@PathParam("id") int id) {}
Run Code Online (Sandbox Code Playgroud)
导致进入/捕获组.因此,当Jersey尝试解析时/1,它将获得一个异常并发送一个404.我们可以使用一个String,但随后它变得丑陋,因为我们需要摆脱领先/ 并自己解析它.
@Path("/myMethod{id: (/\\d+)?}")
public Response get(@PathParam("id") String id) {
id = id.replace("/", "");
int parsed = Integer.parseInt(id);
}
Run Code Online (Sandbox Code Playgroud)
我提出的另一个解决方案(适用于OP的那个)是/将数字与数字分成两个不同的路径表达式,这样前导/不会在实际的id中被捕获并且在解析时不会失败
@Path("/method{noop: (/)?}{id: ((?<=/)\\d+)?}")
public Response get(@PathParam("id") int id) {}
Run Code Online (Sandbox Code Playgroud)
在{noop: (/)?}捕获可选/.并{id: ((?<=/)\\d+)?}使用一个积极的lookbehind,说\\d+当且仅当/在它之前有((?<=/))时才允许数字().这是必要的,因为它/是可选的.如果我们不使用这个断言,那么/myMethod123将被允许.
这是一个使用Jersey Test Framework的完整测试用例
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());
}
}
Run Code Online (Sandbox Code Playgroud)
这是测试的依赖关系
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>${jersey2.version}</version>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
对于测试,最好使用boxed Integer而不是an int作为方法参数.使用前者,您可以进行空检查,而不是接收0基元的默认值.
ccl*_*eve 10
有一种方法更简单的方法来做到这一点:
@GET
@Path("myMethod/{id}")
public String myMethod(@PathParam("id") Integer id) {
}
@GET
@Path("myMethod")
public String myMethod() {
return myMethod(null);
}
Run Code Online (Sandbox Code Playgroud)
不需要棘手的正则表达式.
| 归档时间: |
|
| 查看次数: |
5628 次 |
| 最近记录: |