2012-03-06 52 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) { 
     ... 
    } 
} 

現在可以說,我需要添加其他的MediaType,QueryParam等,這將導致父資源返回現有JSON,與每個子資源的範圍內它的回報。

JAX-RS或Jersey有沒有辦法輕鬆創建/注入已更改的上下文到子資源中?或者在容器內創建一個子請求?

我目前正在使用一個幼稚的解決方案,我從孩子那裏獲取地圖,然後對其進行後處理以更新以當前路徑爲根的任何URI,但感覺應該有更好的解決方案(其中在事實之後不需要重映射地圖?)

回答

0

不是我所知道的。至少,不是你當前的方法設置的方式。

這裏有一種方式來獲得,諸如此類的功能,但需要不同的架構代碼...

1)使用Response和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點是完全無關的問題。響應/響應構建器與父/子的上下文無關。是的,您的類型簽名很漂亮,但我可以擁有Object的類型簽名並返回任何響應,地圖,外觀和資源,我希望澤西不會在意它可以解釋結果。 – Charlie 2012-03-07 14:04:47

+0

第2點是我考慮過的事情,但感覺它違反了DRY原則。我將有一個Parent實體對象,一個Child實體對象和一個ParentWithChildren實體對象...每個對象都需要自己的自定義MessageBodyWriter(而不是Map )。現在,每次子表示更改時,ParentWithChildren表示都必須更改,並且相應的MessageBodyWriters也必須更改。 – Charlie 2012-03-07 14:13:42

+0

您好查理, 我包括點1不是因爲漂亮的類型簽名,而是因爲它允許您使用一個方法/ URL路徑來服務不同的對象響應,因爲您正在將您的實體封裝在響應對象中。 對於我的第二點來說,當不需要完整的級聯版本時,您不會創建單獨的實體,而只需創建這些實體的外觀或遮罩。如果底層實體發生變化,那麼您需要更新facade/mask類,但如果您保留了實體中的所有邏輯,這應該比更新單獨的方法更有用。 – hypno7oad 2012-03-07 14:51:20