2012-12-13 3 views
0

JAX-RS를 사용하여 RESTful API를 개발 중입니다. 다음과 같이 내 API의 단순화 된 버전입니다 :JAX-RS : "기본"하위 리소스 로케이터 제공

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를 처리합니다. SubResourceFactory 구현은이 토론의 목적과 관련이 없습니다. 그것은 단지 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(); 
    } 
} 

: 버전 지정에가있을 때

  • 내가 getDefaultApiResource() 주석 경우는, 그러면 모든 일이 예상 작품으로 API 그러나 getDefaultApiResource()의 주석을 취소하면 요청에 v1.0이 있는지 여부에 관계없이 항상 호출됩니다.
  • getDefaultApiResource()의 주석을 취소하면 버전 지정자없이 GET /appapi/users 일 때 404가 표시됩니다. 내가

그래서, 내 하위 리소스 로케이터 경로/regexps '에 설정 어떻게 방법이 더 버전이 없을 때 호출되도록 (버전 지정자, 즉) GET /appapi/v1.0/users를 사용하지만 만약 일이 잘 작동 요청자의 지정자?

저는 Restlet 프레임 워크를 사용하고 있습니다 만,이 질문은 구현에 의존하지 않습니다.

답변

2

getDefaultApiResource가 항상 호출되는 이유는 URI 패턴이 getVersionedSubResource와 동일한 정규 표현식이며 두 개 이상의 패턴이 요청 URI와 일치 할 때 가장 긴 패턴 (말 그대로 문자가 가장 큰 패턴)이 우선합니다 . ("버전 :"은 패턴의 일부로 간주되지 않습니다.) 자세한 내용은 JAX-RS specification의 3.7.2 섹션을 참조하십시오.

나는 이것을 시도한 적이 없지만 @Path ("")가 원하는대로 할 것이라고 생각합니다. 그런데

, 정규 표현식은 매우 옳지 않다 나타납니다

선택적으로 단일 기간, 숫자 또는 플러스 뒤에 하나 개 이상의 숫자 뒤에 "소문자 V는 말한다
[v]\\d+[[.]\\d+]? 

기호."그것은해야한다 :.. 설명을위한

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

덕분에 나는 정규 표현식에 새로 온 나는 getDefaultApiResource()'에 대한 정규 표현식은'getVersionedSubResource()'에 대한 그의 __negation__이'이후 있다는 가정하에 있었다 – curioustechizen

+0

'@Path ("")'사용에 대한 제안이 효과적이었고,'getVersionedSubResource' "와 일치하지 않는 것은 모두 뒤로 물러 난다. (''')''로 주석이 달린 것에 옮긴다. 정규 표현식에 (일시적인) 변경을가해야만한다. [[v] \\ d + ([.] \)를 사용할 때 Restlet이 이상한'IndexOutOfBoundsException'을 던진다. \ d + [.] \\ d +'(기본적으로 버전 구분자에 메이저 버전과 마이너 버전이 필요하며, 점 분리). 지금 잘 작동하고 있습니다. – curioustechizen

관련 문제