对于最新的稳定版本,请使用 Spring Data REST 4.5.3spring-doc.cadn.net.cn

自定义 Spring Data REST

有很多选项可以定制 Spring Data REST。这些小节展示了如何作。spring-doc.cadn.net.cn

自定义项资源 URI

默认情况下,项资源的 URI 由用于集合资源的路径段组成,并附加了数据库标识符。 这允许您使用存储库的findOne(…)查找实体实例的方法。 从 Spring Data REST 2.5 开始,可以通过使用RepositoryRestConfiguration(在 Java 8 上首选)或通过注册EntityLookup作为应用程序中的 Spring bean。 Spring Data REST 会选择这些并根据其实现调整 URI 生成。spring-doc.cadn.net.cn

假设一个User使用username唯一标识它的属性。 进一步假设我们有一个Optional<User> findByUsername(String username)方法。spring-doc.cadn.net.cn

在 Java 8 上,我们可以将映射方法注册为方法引用来调整 URI 创建,如下所示:spring-doc.cadn.net.cn

@Component
public class SpringDataRestCustomization implements RepositoryRestConfigurer {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.withEntityLookup()
      .forRepository(UserRepository.class)
      .withIdMapping(User::getUsername)
      .withLookup(UserRepository::findByUsername);
  }
}

forRepository(…)将存储库类型作为第一个参数,将存储库域类型映射到某个目标类型的方法引用作为第二个参数,以及另一个方法引用,使用提到的存储库作为第一个参数映射回该值。spring-doc.cadn.net.cn

如果您没有运行 Java 8 或更高版本,则可以使用该方法,但它需要一些非常冗长的匿名内部类。 在较旧的 Java 版本上,您可能更喜欢实现UserEntityLookup类似于以下内容:spring-doc.cadn.net.cn

@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-doc.cadn.net.cn

自定义存储库公开

默认情况下,所有公共 Spring Data 存储库都用于公开 HTTP 资源,如存储库资源中所述。 受包保护的存储库接口从此列表中排除,因为您表示其功能仅对包内部可见。 这可以通过显式设置RepositoryDetectionStrategy(通常通过枚举RepositoryDetectionStrategies) 开启RepositoryRestConfiguration. 可以配置以下值:spring-doc.cadn.net.cn

  • ALL— 公开所有 Spring Data 存储库,无论其 Java 可见性或注释配置如何。spring-doc.cadn.net.cn

  • DEFAULT— 公开公共 Spring Data 存储库或显式注释的存储库@RepositoryRestResource及其exported属性未设置为false.spring-doc.cadn.net.cn

  • VISIBILITY— 仅公开公共 Spring Data 存储库,而不考虑注释配置。spring-doc.cadn.net.cn

  • ANNOTATED— 仅公开显式注释的 Spring Data 存储库@RepositoryRestResource及其exported属性未设置为false.spring-doc.cadn.net.cn

如果您需要应用自定义规则,只需实现RepositoryDetectionStrategy手动下载。spring-doc.cadn.net.cn

自定义支持的 HTTP 方法

自定义默认曝光

默认情况下,Spring Data REST 公开 HTTP 资源和方法,如存储库资源中所述,存储库基于哪些 CRUD 方法公开。 存储库不需要扩展CrudRepository但也可以有选择地声明上述部分中描述的方法,资源暴露将随之而来。 例如,如果存储库没有公开delete(…)方法,一个 HTTPDELETE将不支持项目资源。spring-doc.cadn.net.cn

如果需要声明一个方法供内部使用,但又不想让它触发 HTTP 方法暴露,可以使用@RestResource(exported = false). 要像这样注释哪些方法以删除对存储库资源中描述的对哪种 HTTP 方法的支持。spring-doc.cadn.net.cn

有时,在方法层面上管理风险敞口还不够细粒度。 例如,save(…)方法用于支持POST在馆藏资源上,以及PUTPATCH在项目资源上。 要有选择地定义应该公开哪些 HTTP 方法,您可以使用RepositoryRestConfiguration.getExposureConfiguration().spring-doc.cadn.net.cn

该类公开了一个基于 Lambda 的 API 来定义全局规则和基于类型的规则:spring-doc.cadn.net.cn

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在所有项目资源上。