1. 引言
Spring Data REST 可以消除 REST 服務中常見的冗餘代碼。
在本教程中,我們將探索如何自定義 Spring Data REST 的 HTTP 綁定默認值。
2. Spring Data REST 倉庫基礎
為了開始,讓我們創建一個空接口,該接口擴展了 CrudRepository 接口,並指定了我們實體類型和其主鍵類型:
public interface UserRepository extends CrudRepository<WebsiteUser, Long> {}默認情況下,Spring 會生成所有需要的映射,配置每個資源通過適當的 HTTP 方法訪問,並返回正確的狀態碼。
如果我們不需要 CrudRepository 中定義的全部資源,我們可以擴展基本的 Repository 接口並僅定義我們想要使用的資源:
public interface UserRepository extends Repository<WebsiteUser, Long> {
void deleteById(Long aLong);
}收到請求後,Spring 會讀取使用的 HTTP 方法,並根據資源類型,調用我們接口中定義的相應方法,如果存在,或者返回 HTTP 狀態碼 405 (方法不允許)。
參考上面的代碼,當 Spring 收到 DELETE 請求時,它會執行我們的 deleteById 方法。
3. 限制暴露的 HTTP 方法
假設我們有一個用户管理系統。我們可能會有一個 UserRepository。
並且,由於我們使用了 Spring Data REST,我們可以從它擴展 CrudRepository 獲得很多好處:
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends CrudRepository<WebsiteUser, Long> {}我們所有的資源都使用默認的 CRUD 模式進行暴露,因此執行以下命令:
curl -v -X DELETE http://localhost:8080/users/<existing_user_id>將返回一個 HTTP 狀態碼 204 (No Content returned) 以確認刪除操作。
現在,假設我們希望阻止第三方訪問 delete 方法,同時允許我們內部使用。
我們可以首先將 deleteById 方法的簽名添加到接口中,這會向 Spring Data REST 告知我們將對其進行配置。
然後,我們可以使用註解 @RestResource(exported = false),它會 配置 Spring 跳過此方法在觸發 HTTP 方法暴露時:
@Override
@RestResource(exported = false)
void deleteById(Long aLong);現在,如果我們重複上面展示的相同的 cUrl 命令,我們將收到 HTTP 狀態碼 405 (方法不允許)。
4. 自定義支持的 HTTP 方法
<em>@RestResource</em> 註解也賦予我們自定義映射到存儲庫方法的 URL 路徑以及 HATEOAS 資源發現返回的 JSON 中的鏈接 ID 的能力。
要做到這一點,我們使用註解的可選參數:
- `path` 用於 URL 路徑
- `rel` 用於鏈接 ID
讓我們回到我們的 <em>UserRepository</em> 並添加一個簡單的 findByEmail 方法:
WebsiteUser findByEmail(@Param("email") String email);通過執行一個對 cUrl 到 http://localhost:8080/users/search/ 的請求,我們現在可以看到我們的新方法列出了與其他資源一起:
{
"_links": {
"findByEmail": {
"href": "http://localhost:8080/users/search/findByEmail{?email}"
},
"self": {
"href": "http://localhost:8080/users/search/"
}
}
}如果我們不滿意默認路徑,而不想更改倉庫方法,我們可以簡單地添加@RestResource註解
@RestResource(path = "byEmail", rel = "customFindMethod")
WebsiteUser findByEmail(@Param("email") String email);如果再次執行資源發現,生成的JSON將確認我們的更改:
{
"_links": {
"customFindMethod": {
"href": "http://localhost:8080/users/search/byEmail{?email}",
"templated": true
},
"self": {
"href": "http://localhost:8080/users/search/"
}
}
}5. 編程配置
有時我們需要更精細的配置級別,以暴露或限制對我們 HTTP 方法的訪問。例如,在集合資源上的 POST 請求以及在項目資源上的 PUT 和 PATCH 請求都使用相同的 save 方法。
從 Spring Data REST 3.1 開始,並在 Spring Boot 2.1 中可用,我們可以通過 ExposureConfiguration 類更改特定 HTTP 方法的暴露。 此配置類暴露了一個基於 lambda 的 API,用於定義全局規則和基於類型的規則。
例如,我們可以使用 ExposureConfiguration 來限制對 UserRepository 的 PATCH 請求:
public class RestConfig implements RepositoryRestConfigurer {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration restConfig,
CorsRegistry cors) {
ExposureConfiguration config = restConfig.getExposureConfiguration();
config.forDomainType(WebsiteUser.class).withItemExposure((metadata, httpMethods) ->
httpMethods.disable(HttpMethod.PATCH));
}
}6. 結論
在本文中,我們探討了如何配置 Spring Data REST 以自定義資源中默認支持的 HTTP 方法。