背景:我们之前使用Jersey构建了一个RESTful API,我们将uri /items.json映射到id的json数组和/items/{id}.json到单个项的json对象。现在我们要为每个项目创建一个包含一些元数据的列表,并希望使用像/items.data.json这样的选择器,类似于apache sling。
到目前为止:我只是扩展了UriConnegFilter来解析uri以获得额外的后缀,如下所示:
public class UriSelectorFilter extends UriConnegFilter {
protected List<String> selectors; // this list is populated in the constructor
public ContainerRequest filter(ContainerRequest request) {
super.filter(request);
// search for suffix in last path segment, see http://java.net/projects/jersey/sources/svn/content/trunk/jersey/jersey-server/src/main/java/com/sun/jersey/api/container/filter/UriConnegFilter.java?rev=5034
final String[] suffixes = segment.getPath().split("\\.");
for (int i = suffixes.length - 1; i >= 1; i--) {
final String suffix = suffixes[i];
if(selectors.contains(suffix)) {
request.getQueryParameters().putSingle("selector", suffix);
final int index = path.lastIndexOf('.' + suffix);
path = new StringBuilder(path).delete(index, index + suffix.length() + 1).toString();
suffixes[i] = "";
}
}
if (length != path.length()) {
request.setUris(
request.getBaseUri(),
request.getRequestUriBuilder().replacePath(path).build());
}
return request;
}
}
此过滤器工作正常,它找到了我的uri的选择器部分,并向请求对象添加了一个查询参数。但是在我的资源中我添加了一个@QueryParam属性,该属性只填充了默认值而不是添加的查询值:
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getItemsJSON(@DefaultValue("id") @QueryParam("selector") String selector) {
// query param is not filled with the selector that was found in the UriSelectorFilter
}
是否有人建议如何使用检测到的选择器提供我的资源?有没有比使用QueryParam更好的方法? (注意:如果我将查询添加到我的网址,例如'?selector = something',那么该属性就会正确填充。)
非常感谢任何帮助。
答案 0 :(得分:0)
您需要另一个使用@PathParam
注释的参数,并且需要在@Path
注释中(在方法或类上)指定如何将这些位绑定在一起。例如,要处理类似/items/foobar42/data.json
的路径,您可以执行此操作:
@GET
@Path("/items/{item}/data.json")
@Produces(MediaType.APPLICATION_JSON)
public Response getItemsJSON(@PathParam("item") String itemId,
@DefaultValue("id") @QueryParam("selector") String selector) {
// Now you've got an itemId and a possible selector...
}
尝试使用过滤器进行所有映射...这对我来说似乎很难,因为有一个很好的声明方式来代替它。您甚至可以在@Path
中指定正则表达式,以便匹配更复杂的变量部分;我在自己的代码中这样做,以创建一个可以服务于整个分层文件系统的方法。
(请注意,{
中的}
支撑@Path
项应与@PathParam
注释中的名称匹配,并且您可以从路径中匹配多个项目必要的;只需使用几个@PathParam
- 带注释的参数。)