2014-09-25 101 views
1

基礎上的樣本項目https://spring.io/guides/gs/accessing-data-rest/https://github.com/jcoig/gs-accessing-data-rest)我有庫定義如下:如何全局定製Spring Data REST資源的集合資源rel和路徑?

@RepositoryRestResource 
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> { 
    List<Person> findByLastName(@Param("name") String name); 
} 

這樣定義的庫通過http://localhost:8080/persons可用並且反應是:

{ 
    "_links" : { 
    "self" : { 
     "href" : "http://localhost:8080/persons{?page,size,sort}", 
     "templated" : true 
    }, 
    "search" : { 
     "href" : "http://localhost:8080/persons/search" 
    } 
    }, 
    "_embedded" : { 
    "persons" : [ { 
     "firstName" : "John", 
     "lastName" : "Smith", 
     "_links" : { 
     "self" : { 
      "href" : "http://localhost:8080/persons/1" 
     } 
     } 
    } ] 
    }, 
    "page" : { 
    "size" : 20, 
    "totalElements" : 1, 
    "totalPages" : 1, 
    "number" : 0 
    } 
} 

我不想在URL中有persons,我不想讓persons作爲返回的JSON中的關鍵字。當然,我也確定我的倉庫如下:

@RepositoryRestResource(collectionResourceRel = "key", path = "path") 
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> { 
    List<Person> findByLastName(@Param("name") String name); 
} 

但我的問題是如何改變默認的Spring的行爲,得到了自定義鍵和自定義路徑提供商(就像例如禁用s後綴)。

回答

1

讓我們確保我們首先想要實現的目標:Spring Data REST公開了兩種主要資源:集合資源和項目資源。爲了能夠區分兩者,我們需要兩個不同的關係名稱。因此,默認情況下,Spring Data REST使用項目資源rel和Evo Inflector庫的非大寫域名類來複用項目資源rel並將其用作集合關係名稱(實際上您非正式地描述爲添加後綴)。

如果您手動排除Evo Inflector庫,則Spring Data REST將回退到${itemRel}List以收集關係,首先比使用正確複數名稱更笨拙。

正如您已經發現的那樣,您可以手動配置要用於每個存儲庫的名稱。 但是,將收集資源rel配置爲項目資源rel是一個非常糟糕的主意,因爲這會阻止客戶端區分這兩種資源類型。

假設你走了這麼遠讀,還是要部署在全球範圍內改變了類型的關係名就可以實現自定義策略RelProvider(參見實施例EvoInflectorRelProviderDefaultRelProvider)。如果您將該實現註冊爲Spring bean。

@Configuration 
class MyConfig { 

    @Bean 
    YourCustomRelProvider customRelProvider() { 
    return new YourCustomRelProvider(…); 
    } 
} 

您可能想實驗的執行順序(見@OrderOrdered接口),以確保您的自定義提供選擇有利於註冊的默認的的。

+0

感謝您的回覆! 不幸我仍然得不到我想要的東西... 在(沒有'collectionResourceRel'和'path')我添加了一個實現'RelProvider'的類,註解'Component'和'Order(value = Ordered.HIGHEST_PRECEDENCE)' 和三重寫的方法: 'getItemResourceRelFor'(返回'「iii」'), 'getCollectionResourceRelFor'(返回''ccc「')和 'supports'(返回'true')。 在'Application.java'中,我添加了bean,就像在你的答案中一樣......我仍然在JSON的鍵和URL中獲得了'persons'。 我在做什麼錯? – jcoig 2014-09-29 05:59:25

+0

這就是我們如何處理事情,它似乎工作。是否它所有的頁面都有項目,因此頁面界面被標準化。你能確認你的組件正在註冊爲bean嗎? (確保你的支持方法被調用)組件中的組件標註和bean方法是多餘的......但仍然可以工作。我們不需要執行訂單註釋。我們也是春季啓動 – 2014-10-07 19:52:13

+0

克里斯,請看這個項目:https://github.com/jcoig/gs-accessing-data-rest。 它基於http://spring.io/guides/gs/accessing-data-rest/,基於奧利弗的提示進行更改(或者根據我的理解)。 – jcoig 2014-10-08 06:02:07

2

如果定製RelProvider例如施加@Order(value = Ordered.HIGHEST_PRECEDENCE)的解決方案是行不通以下解決方法可能會有所幫助:

@Configuration 
@Import(RepositoryRestMvcConfiguration.class) 
public class RestMvcConfigurer extends RepositoryRestMvcConfiguration 
{ 
... 
@Override 
public ResourceMappings resourceMappings() 
{ 

    final Repositories repositories = repositories(); 
    final RepositoryRestConfiguration config = config(); 
    return new RepositoryResourceMappings(config, repositories, new YourCustomRelProvider()); 
} 
} 

而且我必須排除evo-inflector從classpath:

<dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-data-rest</artifactId> 
     <exclusions> 
      <exclusion> 
       <groupId>org.atteo</groupId> 
       <artifactId>evo-inflector</artifactId> 
      </exclusion> 
     </exclusions> 
    </dependency> 

不是一個真正的很好的解決方案,但它適用於我的設置。

+0

感謝您的回覆Dominik!有用!現在,我在'href'中使用'ccc'作爲響應JSON中的一個鍵,'http:// localhost:8080/person {?page,size,sort}'。剩下的問題是如何在不使用'@ RepositoryRestResource'註釋中的'path'參數的情況下更改此路徑。 – jcoig 2014-10-15 09:50:12

+0

我不知道你的意思是通過改變路徑。如果引用基本URI,則可以在'RestMvcConfigurer'中覆蓋'protected void configureRepositoryRestConfiguration(最終RepositoryRestConfiguration配置)'方法。其中調用'config.setBaseUri(「mybaseuri」)'。 – 2014-11-17 16:34:32

+0

返回的JSON在兩個不同的位置包含單詞「persons」:作爲'_embedded'和幾個hrefs中的一個鍵。我想在這些hrefs中更改路徑,而不在'@RepositoryRestResource'註釋中指定'path =「path」'。 – jcoig 2014-11-19 09:27:24