在JAX-RS/Jersey中为java包添加资源路径段?

在JAX-RS/Jersey中为java包添加资源路径段?,java,jax-rs,jersey-2.0,Java,Jax Rs,Jersey 2.0,我用的是泽西2.19。我想支持我的API的两个版本。为此,我希望有两条主要路径:/api/v1和/api/v2。我想要两个包com.test.v1(使用v1api资源)和com.test.v2(使用v2api资源) 我知道如何为整个应用程序定义路径,我将在我的ResourceConfig类上使用@ApplicationPath('api')。但是,如何定义包com.test.v1资源位于/v1命名空间中,包com.test.v2资源位于/v2命名空间中?目前,除了在每个@Path注释中添加'v1

我用的是泽西2.19。我想支持我的API的两个版本。为此,我希望有两条主要路径:
/api/v1
/api/v2
。我想要两个包
com.test.v1
(使用v1api资源)和
com.test.v2
(使用v2api资源)

我知道如何为整个应用程序定义路径,我将在我的
ResourceConfig
类上使用
@ApplicationPath('api')
。但是,如何定义包
com.test.v1
资源位于
/v1
命名空间中,包
com.test.v2
资源位于
/v2
命名空间中?目前,除了在每个
@Path
注释中添加'v1'和'v2'前缀外,我看不到其他选项,例如:
@Path('v1/something')
@Path('v2/something')
前缀到每个资源中。这是大量的冗余


有更好的方法吗?

下面是实现这一点的一种方法的概念证明。我从来没有使用过这个,所以我不能提供任何证据来证明任何维护性问题,这些问题可能会或可能不会出现在大型项目中。我刚刚测试了一个简单的项目

它基本上使用Jersey的将版本附加到原始路径

import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.ext.Provider;
import org.glassfish.jersey.server.model.ModelProcessor;
import org.glassfish.jersey.server.model.Resource;
import org.glassfish.jersey.server.model.ResourceModel;

@Provider
public class VersioningModelProcessor implements ModelProcessor {

    private Map<String, String> packageAppenders = new HashMap<>();

    {
        packageAppenders.put("com.stackoverflow.jersey.v1", "v1");
        packageAppenders.put("com.stackoverflow.jersey.v2", "v2");
    }

    @Override
    public ResourceModel processResourceModel(ResourceModel model, Configuration config) {

        // Create new resourc model.
        ResourceModel.Builder newModelBuilder = new ResourceModel.Builder(false);
        for (final Resource resource: model.getResources()) {

            // Look for the package
            String path = resource.getPath();
            Class handlerClass = resource.getHandlerClasses().iterator().next();
            String pkg = handlerClass.getPackage().getName();

            // Match the packge to our map of packages
            if (packageAppenders.containsKey(pkg)) {

                // append the version
                String version = packageAppenders.get(pkg);
                path = version + "/" + path.replace("/", "");

                Resource.Builder resourceBuilder = Resource.builder(resource);
                resourceBuilder.path(path);

                Resource newResource = resourceBuilder.build();
                System.out.println(newResource.toString());

                // add the new resource with the new path.
                newModelBuilder.addResource(newResource);
            } else {
                // Do nothing. Just add the resource as normal
                newModelBuilder.addResource(resource);
            }
        }
        return newModelBuilder.build();
    }

    @Override
    public ResourceModel processSubResource(ResourceModel model, Configuration config) {
        return model;
    }
}
import java.util.HashMap;
导入java.util.Map;
导入javax.ws.rs.core.Configuration;
导入javax.ws.rs.ext.Provider;
导入org.glassfish.jersey.server.model.ModelProcessor;
导入org.glassfish.jersey.server.model.Resource;
导入org.glassfish.jersey.server.model.ResourceModel;
@提供者
公共类VersioningModelProcessor实现ModelProcessor{
私有映射包appenders=newhashmap();
{
packageAppenders.put(“com.stackoverflow.jersey.v1”、“v1”);
packageAppenders.put(“com.stackoverflow.jersey.v2”、“v2”);
}
@凌驾
公共资源模型processResourceModel(资源模型模型,配置){
//创建新的资源模型。
ResourceModel.Builder newModelBuilder=newresourcemodel.Builder(false);
for(最终资源:model.getResources()){
//寻找包裹
字符串路径=resource.getPath();
Class handlerClass=resource.getHandlerClasses().iterator().next();
字符串pkg=handlerClass.getPackage().getName();
//将包装与我们的包装图相匹配
if(包装附件集装箱(包装)){
//附加版本
字符串版本=packageAppenders.get(pkg);
路径=版本+“/”+路径。替换(“/”,“”);
Resource.Builder resourceBuilder=Resource.Builder(资源);
resourceBuilder.path(path);
Resource newResource=resourceBuilder.build();
System.out.println(newResource.toString());
//使用新路径添加新资源。
newModelBuilder.addResource(newResource);
}否则{
//什么也不做。只需像平常一样添加资源
newModelBuilder.addResource(资源);
}
}
返回newModelBuilder.build();
}
@凌驾
公共资源模型processSubResource(资源模型模型,配置配置){
收益模型;
}
}

可能比它的价值更麻烦。我不知道。你可以做评判。

最后我决定只配置和部署2个Jersey servlet。API的V1在模块_V1中,V2在模块_V2中,我有两个servlet和2个ResourceConfig。第一个资源配置定义路径“v1”,第二个“v2”,它们都与“api”的根相关。这非常有效,允许简单地删除任何版本。

我将接受您的回答,因为它回答了我的原始问题。我最终选择了另一条路,请看我的答案。@wujek是的,我完全忘了怎么做。我会接受你自己的回答。这更有意义。