2012-03-06 5 views
3

리소스를 가지고있어 (JSON을 생성하는) 몇 개의 하위 리소스에 대한 링크를 반환하는 JSON을 생성합니다. 이 리소스는 트리의 여러 지점에서 포함될 수 있으므로 absolutePathBuilder를 사용하여 하위 리소스에 대한 링크를 만듭니다.하위 요청에서 하위 리소스 메서드를 호출 하시겠습니까?

public class AResource { 
    @GET 
    @Produces(MediaType.APPLICATION_JSON + ";charset=utf8") 
    public Map<String, Object> getRoot(@Context final UriInfo info) { 
     final Map<String, Object> toReturn = new HashMap<String, Object>(); 
     final String[] children = { "one", "two", "thrée" }; 
     final UriBuilder builder = info.getAbsolutePathBuilder().path("{child}"); 
     for (final String child : children) { 
      toReturn.put(child, builder.build(child).toASCIIString()); 
     } 
     return toReturn; 
    } 

    @Path("{child:(one|two|thrée)}") 
    public ChildResource getChild(@PathParam("child") final String child) { 
     return new ChildResource("AResource " + child); 
    } 
} 
public class ChildResource { 
    public Map<String, Object> getRoot(@Context final UriInfo info) { 
     ... 
    } 
} 

은 이제 학부모 자원이 내 자식 각 자원의 반환과 함께, 기존의 JSON을 반환하는 원인이 다른 MediaType에, QueryParam 등을 추가 할 필요가 말할 수 있습니다.

하위 리소스에 변경된 컨텍스트를 쉽게 만들거나 삽입 할 수있는 JAX-RS 또는 Jersey의 방법이 있습니까? 또는 컨테이너 내에서 하위 요청을 만드시겠습니까?

저는 현재 자식에서지도를 가져 와서 현재 경로에 뿌리를 둔 URI를 업데이트하기위한 사후 처리를하는 순진한 해결책으로 작업하고 있지만 더 나은 해결책이 있어야합니다. 사실 이후 맵을 다시 해싱 할 필요가 없습니까?)

답변

0

아니요. 적어도 현재의 방법이 설정되는 방식이 아닙니다.

여기

1) 당신의 실체를 포장 응답 및 ResponseBuilder 클래스를 사용 ... 기능의 종류를 얻을 수있는 방법이지만, 다른 코드를 아키 필요합니다. 응답 상태 사용자 정의를 제공 할 수있을뿐만 아니라 QueryParams에 응답하여 전달하는 엔티티를 조정할 수있는 방법을 허용 할 수도 있습니다 ...

2) 여러 버전을 제공해야하는 경우 그런 다음 엔티티의 Facades를 만듭니다. 기본적으로 JSON 응답을 표시하려는 구조를 포함하는 클래스를 작성하십시오. 귀하의 경우, 하나는 자식 문자열을 URL 문자열로 나타내지 만 다른 하나는 단순히 자식 개체를 포함합니다.

public class ParentResource{ 
    @GET 
    @Produces("application/json") 
    public Response getParent(
    @Context UriInfo uriInfo 
    , @DefaultValue("false") @QueryParam("cascade") Boolean cascade 
) { 
    if(cascade) 
     //This assumes that your ParentEntity stores the child objects already. 
     return Response.ok().entity(new ParentEntity).build(); 
    else 
     return Response.ok().entity(new ParentFacadeWithURLS(uriInfo)).build(); 
    } 
} 

편집 # 1 2012.03.07

public class AResource { 
    @GET 
    @Produces("application/json") 
    public Map<String, Object> getRoot(
     @Context final UriInfo info 
     , @DefaultValue("false") @QueryParam("cascade") Boolean cascade 
    ) { 
     final Map<String, Object> toReturn = new HashMap<String, Object>(); 
     final String[] children = { "one", "two", "thrée" }; 
     if(cascade){ 
     ChildResource cr= new ChildResource(); 
     toReturn.put(child, cr.getRoot(uriInfo)); 
     } else { 
     final UriBuilder builder = info.getAbsolutePathBuilder().path("{child}"); 
     for (final String child : children) { 
      toReturn.put(child, builder.build(child).toASCIIString()); 
     } 
     } 
     return toReturn; 
    } 

    @GET 
    @Path("{child:(one|two|thrée)}") 
    public ChildResource getChild(@PathParam("child") final String child) { 
     ChildResource cr = new ChildResource(); 
     return new cr.getRoot(child); 
    } 
} 
+0

포인트 1 질문에 전혀 관계가없는 것입니다. 응답/응답 빌더는 부모/자식의 컨텍스트와 아무 관련이 없습니다. 예, 타입 시그니처는 예쁘지만 오브젝트의 타입 시그니처를 가질 수 있고, 응답, 맵, 외관, 원하는 리소스를 반환 할 수 있습니다. 저지는 결과를 해석 할 수있는 한 신경을 쓰지 않을 것입니다. – Charlie

+0

포인트 2는 내가 생각했던 것 이었지만 DRY 원리를 위반하는 것 같았습니다. 부모 엔티티 객체, 하위 엔티티 객체 및 ParentWithChildren 엔티티 객체가있을 것입니다. 각 객체에는 사용자 정의 MessageBodyWriter가 필요합니다 (Map 대신). 이제는 하위 표현이 변경 될 때마다 ParentWithChildren 표현이 변경되어야하며 해당 MessageBodyWriters도 변경해야합니다. – Charlie

+0

안녕하세요 Charlie, 포인트 유형 1은 예쁜 형식 시그니처가 아니기 때문에 하나의 메소드/URL 경로를 사용하여 다른 객체 응답을 제공 할 수 있으므로 응답 객체 내에 엔티티를 캡슐화하고 있기 때문에 포인트 1을 포함합니다. 제 2 지점에서는 별도의 엔티티를 만들지 않고 전체 캐스케이드 버전이 필요없는 경우 해당 엔티티의 외관 또는 마스크 만 만듭니다. 기본 엔티티가 변경된 경우 예를 들어 facade/mask 클래스를 업데이트해야하지만 이는 엔티티에 모든 로직을 보관하는 경우 별도의 메소드를 업데이트하는 것보다 더 많은 작업이 필요합니다. – hypno7oad

관련 문제