Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JAX-RS:提供一个;“违约”;子资源定位器_Java_Regex_Rest_Jax Rs_Restlet - Fatal编程技术网

Java JAX-RS:提供一个;“违约”;子资源定位器

Java JAX-RS:提供一个;“违约”;子资源定位器,java,regex,rest,jax-rs,restlet,Java,Regex,Rest,Jax Rs,Restlet,我正在使用JAX-RS开发RESTful API。我的API的简化版本如下: GET /appapi/v1.0/users POST /appapi/v1.1/users ... ... and so on 如您所见,该模式遵循{api_name}/v{major_version}.{minor_version}/{rest_of the_path} 我还有一个额外的要求: 如果未指定版本,则默认情况下应使用最新版本-即 GET/appapi/users应等同于GET/appapi/v1.1

我正在使用JAX-RS开发RESTful API。我的API的简化版本如下:

GET /appapi/v1.0/users
POST /appapi/v1.1/users

... ... and so on
如您所见,该模式遵循
{api_name}/v{major_version}.{minor_version}/{rest_of the_path}

我还有一个额外的要求:

如果未指定版本,则默认情况下应使用最新版本-即

GET/appapi/users
应等同于
GET/appapi/v1.1/users
(假设1.1是用户的最新版本)

这就是我如何使用JAX-RS实现的

@Path("/appapi")
public class AppApiRootResource {

    @Path("/{version: [v]\\d+[[.]\\d+]?}/")
    public AppApiSubResource getVersionedSubResource
                            (@PathParam("version") String version){
        System.out.println("Version: "+version);
        String versionString = version.substring(1); //Discard the leading 'v'
        String majorVersion = "";
        String minorVersion = "0";
        if(versionString.contains(".")){
            String [] splits = versionString.split(".");
            majorVersion = splits[0];
            minorVersion = splits[1];
        } else {
            majorVersion = versionString;
        }

        return SubResourceFactory.getSubResource(majorVersion, minorVersion);

    }

    @Path("/{^([v]\\d+[[.]\\d+]?)}/") //Is This Correct??
    public AppApiSubResource getDefaultApiResource(){
        /*
         * Need help defining the regular expression here 
         * so that this is used for anything that doesn't match
         * the "version" regexp above
         */
        System.out.println("API version not specified; Using default version");
        return SubResourceFactory.getLatestVersionSubResource();
    }
}
我的子资源类定义如下。我有这个类的子类来处理API的多个版本。
子资源工厂
的实现与本讨论的目的无关。它只返回
AppApiSubResource
或其子类的实例

public class AppApiSubResource {


    /**
     * Create a new user
     */
    @POST
    @Path("users")
    @Consumes(MediaType.APPLICATION_XML)
    public Response createUser(String newUser, @Context UriInfo uriInfo) {
        URI uri = uriInfo.getAbsolutePathBuilder().path("10")).build();       
        return Response.created(uri).build();
    }

    /**
     * Get a user
     */
    @GET
    @Path("users/{id}")
    @Produces(MediaType.APPLICATION_XML)
    public Response getUser(@PathParam("id") String userId
            ) {

        return Response.ok().entity("<user></user>").build();
    }
}
公共类AppApiSubResource{
/**
*创建新用户
*/
@职位
@路径(“用户”)
@使用(MediaType.APPLICATION_XML)
公共响应createUser(字符串newUser,@Context UriInfo UriInfo){
URI=uriInfo.getAbsolutePathBuilder().path(“10”).build();
返回Response.created(uri.build();
}
/**
*获取用户
*/
@得到
@路径(“用户/{id}”)
@生成(MediaType.APPLICATION\u XML)
公共响应getUser(@PathParam(“id”)字符串userId
) {
返回Response.ok().entity(“”.build();
}
}
问题陈述:

  • 如果我注释掉
    getDefaultApiResource()
    ,那么当API中有一个版本说明符时,事情就会按预期进行。但是,如果我取消注释
    getDefaultAPIROURCE()
    ,则无论请求中是否包含v1.0,都会始终调用它
  • 另外,如果我取消注释
    getDefaultAPIROURCE()
    ,当我执行
    get/appapi/users
    (即,没有版本说明符)时,我会得到一个404;但是,如果我使用
    GET/appapi/v1.0/users
    (即,使用版本说明符),一切都会正常工作
那么,如何设置子资源定位器路径/regexp,以便在请求中没有版本说明符时调用该方法


我使用的是Restlet框架,但这个问题与实现无关。

总是调用GetDefaultAPIROURCE的原因是它的URI模式与getVersionedSubResource的URI模式是相同的正则表达式,并且当多个模式匹配请求URI时,最长的模式(字面上说,是具有最多字符的模式)赢了。(“版本:”不被视为模式的一部分。)有关所有详细信息,请参阅的第3.7.2节

我从未尝试过这个,但我认为@Path(“”)可以满足您的需求

顺便说一下,您的正则表达式似乎不太正确:

[v]\\d+[[.]\\d+]?
表示“小写v,后跟一个或多个数字,可选地后跟一个句点、数字或加号。”应为:

[v]\\d+([.]\\d+)?

谢谢你的解释。我不熟悉正则表达式。我假设
getDefaultAPIROURCE()
的regexp与
getVersionedSubResource()
的regexp相反,因为我是用
^
启动它的。那不是真的吗?我会试试你的其他建议。你关于使用
@Path(“”
的建议奏效了。任何与
getVersionedSubResource
不匹配的内容都会返回到用
@Path(“”
注释的内容。我不得不对正则表达式做一些(临时)修改。当我使用
[v]\\d+([.]\\d+)
时,Restlet抛出一些奇怪的
索引outofboundsexception
。我将其替换为
[v]\\d+[.]\\d+
(基本上,我要求版本说明符同时具有主版本和次版本,并用点分隔)。现在一切正常。