天天看點

Spring認證中國教育管理中心-Spring Data REST架構教程三

原标題:Spring認證中國教育管理中心-Spring Data REST架構教程三(Spring中國教育管理中心)

5.2.排序

Spring Data REST 識别使用存儲庫排序支援的排序參數。

要根據特定屬性對結果進行排序,請添加一個sortURL 參數,其中包含要對結果進行排序的屬性的名稱。您可以通過将逗号 ( ,)附加到屬性名稱加上asc或來控制排序的方向desc。以下将使用在名稱以字母“K”開頭的所有實體findByNameStartsWith上定義的查詢方法,并添加排序資料,以降序對屬性上的結果進行排序:

PersonRepositoryPersonname

curl -v "http://localhost:8080/people/search/nameStartsWith?name=K&sort=name,desc"

要按多個屬性對結果進行排序,請sort=PROPERTY根據需要繼續添加盡可能多的參數。它們Pageable按照它們在查詢字元串中出現的順序添加到中。結果可以按頂級和嵌套屬性排序。使用屬性路徑表示法來表達嵌套排序屬性。不支援按可連結的關聯(即頂級資源的連結)排序。

6.領域對象表示(Object Mapping)

Spring Data REST 傳回Accept與 HTTP 請求中指定的類型相對應的域對象的表示。

目前,僅支援 JSON 表示。将來可以通過添加适當的轉換器并使用适當的内容類型更新控制器方法來支援其他表示類型。

有時,Spring Data REST 的行為ObjectMapper(已專門配置為使用可以将域對象轉換為連結并再次傳回的智能序列化程式)可能無法正确處理您的域模型。您可以通過多種方式建構資料,以至于您可能會發現自己的域模型沒有正确轉換為 JSON。在這些情況下,嘗試以通用方式支援複雜的域模型有時也是不切實際的。有時,根據複雜性,甚至不可能提供通用解決方案。

6.1.向 Jackson 的 ObjectMapper 添加自定義序列化器和反序列化器

為了适應最大比例的用例,Spring Data REST 非常努力地嘗試正确呈現您的對象圖。它嘗試将非托管 bean 序列化為普通 POJO,并嘗試在必要時建立指向托管 bean 的連結。但是,如果您的域模型不容易讀取或寫入純 JSON,您可能需要使用您自己的自定義映射、序列化器和反序列化器來配置 Jackson 的 ObjectMapper。

6.1.1.抽象類注冊

您可能需要挂鈎的一個關鍵配置點是在域模型中使用抽象類(或接口)時。預設情況下,Jackson 不知道為接口建立什麼實作。考慮以下示例:

@Entity

public class MyEntity {

@OneToMany

private List interfaces;

}

在預設配置中,Jackson 不知道在向導出器釋出新資料時要執行個體化哪個類。這是您需要通過注釋或(更幹淨地)通過使用Module.

要将您自己的 Jackson 配置添加到ObjectMapperSpring Data REST 使用的配置中,請覆寫該

configureJacksonObjectMapper方法。該方法被傳遞一個ObjectMapper執行個體,該執行個體具有處理序列化和反序列化PersistentEntity對象的特殊子產品。您也可以注冊自己的子產品,如以下示例所示:

@Override

protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {

objectMapper.registerModule(new SimpleModule("MyCustomModule") {

@Override
public void setupModule(SetupContext context) {
  context.addAbstractTypeResolver(
    new SimpleAbstractTypeResolver()
      .addMapping(MyInterface.class, MyInterfaceImpl.class));
}           

});

一旦您可以通路 中的SetupContext對象Module,您就可以做各種很酷的事情來配置 Jackson 的 JSON 映射。您可以Module在Jackson 的 wiki上閱讀有關執行個體如何工作的更多資訊。

6.1.2.為域類型添加自定義序列化程式

如果您想以特殊方式序列化或反序列化域類型,您可以使用 Jackson 注冊您自己的實作,ObjectMapperSpring Data REST 導出器會透明地正确處理這些域對象。要從您的setupModule方法實作中添加序列化程式,您可以執行以下操作:

public void setupModule(SetupContext context) {

SimpleSerializers serializers = new SimpleSerializers();

SimpleDeserializers deserializers = new SimpleDeserializers();

serializers.addSerializer(MyEntity.class, new MyEntitySerializer());

deserializers.addDeserializer(MyEntity.class, new MyEntityDeserializer());

context.addSerializers(serializers);

context.addDeserializers(deserializers);

  1. 預測和摘錄

Spring Data REST 提供了您導出的域模型的預設視圖。但是,有時,您可能出于各種原因需要更改該模型的視圖。本節介紹如何定義預測和摘錄以提供簡化和簡化的資源視圖。

7.1.預測

考慮以下域模型:

public class Person {

@Id @GeneratedValue

private Long id;

private String firstName, lastName;

@OneToOne

private Address address;

Person上例中的對象有幾個屬性:

id 是主鍵。

firstName和lastName是資料屬性。

address 是指向另一個域對象的連結。

現在假設我們建立了一個對應的倉庫,如下:

interface PersonRepository extends CrudRepository<Person, Long> {}

預設情況下,Spring Data REST 導出此域對象,包括其所有屬性。firstName并lastName作為它們的純資料對象導出。關于address屬性有兩個選項。一種選擇是還為Address對象定義一個存儲庫,如下所示:

interface AddressRepository extends CrudRepository<Address, Long> {}

在這種情況下,Person資源将address屬性呈現為其對應Address資源的 URI 。如果我們在系統中查找“Frodo”,我們可能會看到這樣的 HAL 文檔:

{

"firstName" : "Frodo",

"lastName" : "Baggins",

"_links" : {

"self" : {
  "href" : "http://localhost:8080/persons/1"
},
"address" : {
  "href" : "http://localhost:8080/persons/1/address"
}           

還有另一種方法。如果Address域對象沒有自己的存儲庫定義,Spring Data REST 會在Person資源中包含資料字段,如以下示例所示:

"address" : {

"street": "Bag End",
"state": "The Shire",
"country": "Middle Earth"           

},

"self" : {
  "href" : "http://localhost:8080/persons/1"
}           

但是,如果您根本不想要address細節怎麼辦?同樣,預設情況下,Spring Data REST 導出其所有屬性(除了id)。您可以通過定義一個或多個投影為 REST 服務的使用者提供替代方案。以下示例顯示了不包含位址的投影:

@Projection(name = "noAddresses", types = { Person.class })

interface NoAddresses {

String getFirstName();

String getLastName();

該@Projection注釋将其标記為一個投影。該name屬性提供了投影的名稱,稍後我們将更詳細地介紹它。該types屬性的目标這個投影僅适用于Person對象。

它是一個 Java 接口,使其具有聲明性。

它導出firstName.

它導出lastName.

Spring認證中國教育管理中心-Spring Data REST架構教程三

該NoAddresses投影隻有firstName和 的吸氣劑lastName,這意味着它不提供任何位址資訊。假設您有一個單獨的資源存儲庫Address,Spring Data REST 的預設視圖與之前的表示略有不同,如以下示例所示:

"self" : {
  "href" : "http://localhost:8080/persons/1{?projection}", 
  "templated" : true 
},
"address" : {
  "href" : "http://localhost:8080/persons/1/address"
}           

此資源有一個新選項:{?projection}。

該selfURI是URI模闆。

要檢視資源的投影。

提供給projection查詢參數的值與 中指定的值相同@Projection(name = "noAddress")。它與投影界面的名稱無關。

您可以有多個投影。

請參閱投影以檢視示例項目。我們鼓勵您嘗試使用它。

Spring Data REST 查找投影定義如下:

@Projection在與您的實體定義(或其子包之一)相同的包中找到的任何接口都已注冊。

您可以使用 手動注冊投影

RepositoryRestConfiguration.getProjectionConfiguration().addProjection(…)。

無論哪種情況,投影界面都必須有@Projection注釋。

7.1.1.尋找現有的預測

Spring Data REST 公開了Application-Level Profile Semantics (ALPS)文檔,這是一種微中繼資料格式。要檢視 ALPS 中繼資料,請遵循profile根資源公開的連結。如果您向下導航到Person資源的 ALPS 文檔(将是/alps/persons),您可以找到有關Person資源的許多詳細資訊。GET在類似于以下示例的塊中列出了預測以及有關REST 轉換的詳細資訊:

{ …

"id" : "get-person",

"name" : "person",

"type" : "SAFE",

"rt" : "#person-representation",

"descriptors" : [ {

"name" : "projection", 
"doc" : {
  "value" : "The projection that shall be applied when rendering the response. Acceptable values available in nested descriptors.",
  "format" : "TEXT"
},
"type" : "SEMANTIC",
"descriptors" : [ {
  "name" : "noAddresses", 
  "type" : "SEMANTIC",
  "descriptors" : [ {
    "name" : "firstName", 
    "type" : "SEMANTIC"
  }, {
    "name" : "lastName", 
    "type" : "SEMANTIC"
  } ]
} ]           

} ]

的ALPS檔案顯示這部分有關詳細資訊GET和Person資源。

這部分包含projection選項。

這部分包含noAddresses投影。

此投影提供的實際屬性包括firstName和lastName。

如果客戶符合以下條件,則會選取投影定義并提供給客戶:

用@Projection注解标記并位于域類型的同一包(或子包)中,或

使用

RepositoryRestConfiguration.getProjectionConfiguration().addProjection(…).