对于最新的稳定版本,请使用 Spring Data REST 4.4.0! |
自定义 Spring Data REST
有许多选项可以定制 Spring Data REST。这些小节说明了如何作。
自定义项资源 URI
默认情况下,item 资源的 URI 由用于集合资源的路径段组成,并附加了数据库标识符。
这样,您就可以使用存储库的findOne(…)
方法查找实体实例。
从 Spring Data REST 2.5 开始,这可以通过使用RepositoryRestConfiguration
(在 Java 8 上首选)或通过注册EntityLookup
作为应用程序中的 Spring Bean 进行。
Spring Data REST 会拾取这些并根据它们的实现调整 URI 生成。
假设User
替换为username
唯一标识它的属性。
进一步假设我们有一个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 创建要使用的用户名。要按该方法返回的值加载实体实例,我们现在实现lookupEntity(…)
通过使用UserRepository
.
自定义存储库公开
默认情况下,所有公共 Spring Data 存储库都用于公开 HTTP 资源,如 存储库资源中所述。
受软件包保护的存储库接口被排除在此列表中,因为您表示其功能仅对软件包内部可见。
这可以通过显式设置RepositoryDetectionStrategy
(通常通过 enumRepositoryDetectionStrategies
) 打开RepositoryRestConfiguration
.
可以配置以下值:
-
ALL
— 公开所有 Spring Data 存储库,无论其 Java 可见性或 Comments 配置如何。 -
DEFAULT
— 公开公共 Spring Data 存储库或显式注释@RepositoryRestResource
及其exported
属性未设置为false
. -
VISIBILITY
— 无论 Comments 配置如何,都只公开公共 Spring Data 存储库。 -
ANNOTATED
— 仅公开显式注释有@RepositoryRestResource
及其exported
属性未设置为false
.
如果您需要应用自定义规则,只需实施RepositoryDetectionStrategy
手动地。
自定义支持的 HTTP 方法
自定义默认曝光
默认情况下, Spring Data REST 根据存储库公开的 CRUD 方法公开 HTTP 资源和方法,如存储库资源中所述。
存储库不需要扩展CrudRepository
但也可以选择性地声明上述部分中描述的方法,资源公开将随之而来。
例如,如果存储库没有公开delete(…)
方法、HTTPDELETE
将不支持 item 资源。
如果您需要声明一个供内部使用的方法,但不希望它触发 HTTP 方法公开,则可以对存储库方法进行注释@RestResource(exported = false)
.
存储库资源中介绍了要像这样注释哪些方法以删除对哪种 HTTP 方法的支持。
有时,在方法级别管理暴露不够细粒度。
例如,save(…)
method 用于 backPOST
在集合资源上,以及PUT
和PATCH
在 item 资源上。
要有选择地定义应该公开哪些 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 直接创建 item 资源。 |
2 | 禁用对 HTTP 的支持PATCH 在所有 item 资源上。 |