通过查询参数选择Jersey方法

我需要实现一个使用第一个查询参数来识别操作的web服务,即客户端调用类似于: http://localhost:8080/ws/operation?infohttp://localhost:8080/ws/operation?create&name=something

似乎我无法区分使用@Path注释的方法,因为区别特征在于查询参数。 以下示例也是抛出exception:

 package com.example.ws; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.QueryParam; @Path("/operation") public class Operation { @GET public String info(@QueryParam("info") String info) { return "info"; } @GET public String create(@QueryParam("create") String create) { return "create"; } } 

有没有办法根据查询参数指定要使用的方法? 或者我真的必须定义一个方法并在那个方法中检查是否设置了某些查询参数?

我认为Claudio是正确的 – 你可以使用Jersey,但你可以自己处理查询参数,因为它只匹配路径。

您可以注入一个UriInfo并从中提取查询参数:

 @Path("/operation") public class Operation { @Context protected UriInfo info; @GET public String operation() { if (info.getQueryParameters().containsKey("create")) // do stuff else if (info.getQueryParameters().containsKey("info")) // other stuff } 

}

您可以从Jersey切换到另一个框架。 我相信Spring 可以根据查询参数路由到多个方法 。

正如您所提到的,也许您可​​以编写一些更标准的内容,然后将请求重新映射到该内容。 例如,您可以使用Servletfilter或Apache httpd或nginx等前端服务器来修改请求。

从资源角度思考这些操作的作用是什么? 客户账户,电影,股票交易等。为了论证,让我们说它是“Foo”。 你可能会这样:

 @Path("/foo") public class FooResource { @Context protected UriInfo info; @GET @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Foo getById(@QueryParam("id") int id) { // get Foo by id Foo = .... // return an instance of Foo and let Jersey convert it to XML // or JSON depending on the "Accept" header that the client sent return foo; } @POST @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Response create(Foo instance) { // let Jersey deserialize the request body from JSON or XML. // save the instance however you want int id = fooService.save(instance); // return a 204 "created" with a "Location" header URI location = info.getAbsolutePathBuilder().path("{id}").build(id); return Response.created(location).build(); } 

}

听起来你的URI结构是由其他人强制执行的,所以这可能不是你的选择。 如果你继续使用当前的URI结构,那么你应该注意一个主要的缺陷。

根据HTTP 1.1规范 ,GET请求应该是幂等的 。 您的当前设计似乎是使用GET请求创建新的服务器端实例。 存在破损的可能性……中间代理或Web浏览器可以缓存对您的GET请求的响应并阻止创建新实例。

我认为方法选择基于URI的非参数部分。 你不能以客户端调用http://localhost:8080/ws/operation/infohttp://localhost:8080/ws/operation/create?name=something来设计它吗?

这很容易实现:

 @Path("/operation") public class Operation { @GET @Path("info") public String info() { return "info"; } @GET @Path("create") public String create(@QueryParam("name") String name) { return "create"; } } 

我看到这已经得到了解答,但我遇到了类似的问题并使用子资源实现了解决方案。

 package com.example.ws; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.QueryParam; @Path("/") public class Operation { @Path("/") public Object sub(@QueryParam("operation") String operation) { if ("info".equals(operation)) return new InfoOp(); if ("create".equals(operation)) return new CreateOp(); //handle via error code } public class InfoOp { @GET public String info() { return "info"; } } public class CreateOp { @GET public String create(@QueryParam("name") String name) { return "create: " + name; } } }