自定義 Spring Data REST
有許多選項可以定製 Spring Data REST。這些小節將展示如何操作。
自定義項資源 URI
預設情況下,項資源的 URI 由集合資源使用的路徑段與資料庫識別符號組成。這允許您使用倉庫的 findOne(…) 方法查詢實體例項。從 Spring Data REST 2.5 開始,可以透過在 RepositoryRestConfiguration 上使用配置 API(在 Java 8 上首選)或透過將 EntityLookup 的實現註冊為應用程式中的 Spring Bean 來定製此行為。Spring Data REST 會識別這些並根據其實現調整 URI 的生成。
假設有一個具有唯一識別符號 username 屬性的 User。進一步假設我們相應的倉庫中有一個 Optional<User> findByUsername(String username) 方法。
在 Java 8 上,我們可以將對映方法註冊為方法引用來調整 URI 的建立,如下所示:
@Component
public class SpringDataRestCustomization implements RepositoryRestConfigurer {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.withEntityLookup()
.forRepository(UserRepository.class)
.withIdMapping(User::getUsername)
.withLookup(UserRepository::findByUsername);
}
}
forRepository(…) 將倉庫型別作為第一個引數,將倉庫域型別對映到某個目標型別的方法引用作為第二個引數,以及另一個方法引用來使用第一個引數中提到的倉庫將該值映射回去。
如果您沒有執行 Java 8 或更高版本,您可以使用該方法,但這需要一些相當冗長的匿名內部類。在舊的 Java 版本中,您可能應該優先實現一個類似於以下的 UserEntityLookup:
@Component
public class UserEntityLookup extends EntityLookupSupport<User> {
private final UserRepository repository;
public UserEntityLookup(UserRepository repository) {
this.repository = repository;
}
@Override
public Serializable getResourceIdentifier(User entity) {
return entity.getUsername();
}
@Override
public Object lookupEntity(Serializable id) {
return repository.findByUsername(id.toString());
}
}
請注意 getResourceIdentifier(…) 如何返回要用於 URI 建立的使用者名稱。為了透過該方法返回的值載入實體例項,我們現在使用 UserRepository 上可用的查詢方法實現 lookupEntity(…)。
自定義倉庫暴露
預設情況下,所有公共 Spring Data 倉庫都用於暴露 倉庫資源 中描述的 HTTP 資源。包保護的倉庫介面被排除在此列表之外,因為您表達其功能僅在包內部可見。這可以透過在 RepositoryRestConfiguration 上顯式設定 RepositoryDetectionStrategy(通常透過列舉 RepositoryDetectionStrategies)進行定製。可以配置以下值:
-
ALL— 暴露所有 Spring Data 倉庫,無論其 Java 可見性或註解配置如何。 -
DEFAULT— 暴露公共 Spring Data 倉庫或那些顯式使用@RepositoryRestResource註解且其exported屬性未設定為false的倉庫。 -
VISIBILITY— 僅暴露公共 Spring Data 倉庫,無論註解配置如何。 -
ANNOTATED— 僅暴露顯式使用@RepositoryRestResource註解且其exported屬性未設定為false的 Spring Data 倉庫。
如果您需要應用自定義規則,只需手動實現 RepositoryDetectionStrategy。
自定義支援的 HTTP 方法
自定義預設暴露
預設情況下,Spring Data REST 根據倉庫暴露的 CRUD 方法暴露 倉庫資源 中描述的 HTTP 資源和方法。倉庫不需要擴充套件 CrudRepository,也可以選擇性地宣告上述部分中描述的方法,資源的暴露將隨之進行。例如,如果一個倉庫不暴露 delete(…) 方法,則項資源將不支援 HTTP DELETE。
如果您需要宣告一個內部使用的方法,但又不想它觸發 HTTP 方法的暴露,則可以將倉庫方法標註為 @RestResource(exported = false)。關於如何標註哪些方法以取消對哪些 HTTP 方法的支援,請參閱 倉庫資源。
有時在方法級別管理暴露不夠精細。例如,save(…) 方法用於支援集合資源的 POST,以及項資源的 PUT 和 PATCH。要選擇性地定義應該暴露哪些 HTTP 方法,可以使用 RepositoryRestConfiguration.getExposureConfiguration()。
該類公開了一個基於 Lambda 的 API,用於定義全域性和基於型別的規則:
ExposureConfiguration config = repositoryRestConfiguration.getExposureConfiguration();
config.forDomainType(User.class).disablePutForCreation(); (1)
config.withItemExposure((metadata, httpMethods) -> httpMethods.disable(HttpMethod.PATCH)); (2)
| 1 | 停用對直接建立項資源的 HTTP PUT 的支援。 |
| 2 | 停用對所有項資源的 HTTP PATCH 的支援。 |