2015-04-29 59 views
0

根據彈簧HATEOAS guide,資源的列表,每個資源顯示其內容及其鏈接的方式連載分頁時:春HATEOAS:只顯示鏈接,而不序列化的資源/實體

{ 
    "content": [ { 
     "price": 499.00, 
     "description": "Apple tablet device", 
     "name": "iPad", 
     "links": [ { 
      "rel": "self", 
      "href": "http://localhost:8080/product/1" 
     } ], 
     "attributes": { 
      "connector": "socket" 
     } 
    }, { 
     "price": 49.00, 
     "description": "Dock for iPhone/iPad", 
     "name": "Dock", 
     "links": [ { 
      "rel": "self", 
      "href": "http://localhost:8080/product/3" 
     } ], 
     "attributes": { 
      "connector": "plug" 
     } 
    } ], 
    "links": [ { 
     "rel": "product.search", 
     "href": "http://localhost:8080/product/search" 
    } ] 
} 

在大型數據結構的情況下,我認爲(分頁時特別),這將是最好只提供鏈接的資源,而不是資源本身是這樣的:

{ 
    "_links": { 
     "items": [{ 
      "href": "http://localhost:8080/product/1" 
     },{ 
      "href": "http://localhost:8080/product/3" 
     }] 
    } 
} 
從事實

除此之外,這將減少轉移的大小rred字節,這也是由HAL specification建議的。目前,我正在做這種方式

@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 
public ResponseEntity root(Pageable pageable, final PagedResourcesAssembler<Entity> assembler) { 
    Page<Entity> entities = entityRepository.findAll(pageable); 

    PagedResources<Resource> paged = assembler.toResource(entities, 
      EntityResourceAssembler.getInstance()); 

    Collection<Resource> resources = paged.getContent(); 
    ResourceSupport support = new ResourceSupport(); 

    for (Resource r : resources) { 
     Link selfLink = r.getLink(Link.REL_SELF); 
     support.add(new Link(selfLink.getHref(), "items")); 
    } 

    return new ResponseEntity<ResourceSupport>(support, HttpStatus.OK); 
} 

但是,這是一個有點難看,因爲我「手動」需要獲取從資源自身的鏈接。有沒有更好/更聰明的方法來實現我想要的?

回答

1

我會忽略你爲什麼不想嵌入子資源(因此請求響應週期較少,客戶請求中較昂貴的部分),並盡我所能回答你的問題。

你不能使用內置的PagedResourceAssembler做你想做的。取而代之的是從ResourceSupport中獲得一些東西,然後只需自己添加鏈接即可。我們這樣做是在某些情況下,我們只希望,而不是鏈接嵌入資源的(因爲資源不能作爲HAL)

public class PageResource extends ResourceSupport { 

    @XmlAttribute(name = "page") 
    @JsonProperty("page") 
    private PageMeta pageMeta; 

    public PageResource() { 
     this.pageMeta = new PageMeta(); 
    } 

    public PageMeta getPageMeta() { 
     return pageMeta; 
    } 

    public void setPageMeta(PageMeta pageMeta) { 
     this.pageMeta = pageMeta; 
    } 

    public static class PageMeta { 
     //Number of resources on this page. 
     @XmlAttribute @JsonProperty private long size; 
     //Total number of matching resources 
     @XmlAttribute @JsonProperty private long totalElements; 
     //Total number of page 
     @XmlAttribute @JsonProperty private long totalPages; 
     //Current page number 
     @XmlAttribute @JsonProperty private long number; 

     public PageMeta() { 
     } 

     public PageMeta(long size, long totalElements, long totalPages, long number) { 
      this.size = size; 
      this.totalElements = totalElements; 
      this.totalPages = totalPages; 
      this.number = number; 
     } 

     public long getSize() { 
      return size; 
     } 

     public void setSize(long size) { 
      this.size = size; 
     } 

     public long getTotalElements() { 
      return totalElements; 
     } 

     public void setTotalElements(long totalElements) { 
      this.totalElements = totalElements; 
     } 

     public long getTotalPages() { 
      return totalPages; 
     } 

     public void setTotalPages(long totalPages) { 
      this.totalPages = totalPages; 
     } 

     public long getNumber() { 
      return number; 
     } 

     public void setNumber(long number) { 
      this.number = number; 
     } 
    } 
} 

是一個非常簡單的實現,然後在你的控制器,你有責任將下一和prev鏈接,以及項目鏈接。

在這一點上,你可以建立自己的PagedResourceAssembler,只做鏈接,而不是嵌入子資源。

小問題...你應該考慮添加鏈接作爲REL「item」而不是「items」。很容易想到鏈接的集合並給json字段鍵以複數名稱,但記住HAL規範只是使用字段鍵作爲鏈接關係。

比較HTML形式

<link rel="items" src="http://1"/> 
<link rel="items" src="http://2"/> 

<link rel="item" src="http://1"/> 
<link rel="item" src="http://2"/> 

,它的明顯的每個鏈接的目標共享的項目關係到集合,而不是一個「項目」,因爲每個鏈接目標中單個項目集合。

相關問題