问题描述
|
背景:前段时间我们使用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 \'之类的网址中,则该属性会正确填充。)
任何帮助都非常感谢。
解决方法
您需要另一个带有
@PathParam
注释的参数,并且需要在@Path
注释中(在方法或类上)指定如何将这些位绑定在一起。例如,要处理类似“ 4”的路径,您可以这样做:
@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...
}
尝试使用过滤器进行所有映射...鉴于我有一个不错的声明性方法来执行此操作,这对我来说似乎很困难。您甚至可以在3中指定正则表达式,以匹配更复杂的变量部分;我用自己的代码来创建一个可以服务于整个分层文件系统的方法。
(请注意,@Path
中的{
括号}
项应与@PathParam
批注中的名称匹配,并且如有必要,您可以从路径中匹配多个项;只需使用几个带有@PathParam
注释的参数。)