Customizing Spring Data REST
有许多选项可以定制 Spring Data REST。以下小节显示了如何执行此操作。
Customizing Item Resource URIs
默认情况下,项目资源的 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(…)
。
Customizing repository exposure
默认情况下,所有公共 Spring Data 存储库均用于以 Repository resources 中所述方式公开 HTTP 资源。包受保护的存储库接口从该列表中排除,因为您表示其功能仅对内部包可见。通过明确设置 RepositoryDetectionStrategy
(通常通过枚举 RepositoryDetectionStrategies
)上的 RepositoryRestConfiguration
来自定义这一点。可以配置以下值:
-
ALL
——公开所有 Spring Data 存储库,无论其 Java 可见性或注释配置如何。 -
DEFAULT
—公开 Spring Data 资源库或明确标注为 `@RepositoryRestResource`且其 `exported`属性未设置为 `false`的资源库。 -
VISIBILITY
—仅公开公共 Spring Data 资源库,无论其标注配置如何。 -
ANNOTATED
—仅公开明确标注为 `@RepositoryRestResource`且其 `exported`属性未设置为 `false`的 Spring Data 资源库。
如果你需要应用自定义规则,只需手动实现 RepositoryDetectionStrategy
。
Customizing supported HTTP methods
Customizing default exposure
默认情况下,Spring Data REST 会基于存储库公开的 CRUD 方法,公开 Repository resources 中所述的 HTTP 资源和方法。存储库不需要扩展 CrudRepository
,但也可以选择声明上述部分中描述的方法,资源公开也会随之出现。例如,如果存储库不公开 delete(…)
方法,则不支持项目资源的 HTTP DELETE
。
如果您需要声明一个用于内部用途的方法,但不想触发 HTTP 方法公开,可以使用 @RestResource(exported = false)
注释存储库方法。根据 Repository resources 中的描述,要注释哪些方法以取消对哪个 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`的支持。 |