此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Data REST 4.4.0spring-doc.cadn.net.cn

覆盖 Spring Data REST 响应处理程序

有时,您可能希望为特定资源编写自定义处理程序。 要利用 Spring Data REST 的设置、消息转换器、异常处理等,请使用@RepositoryRestController注解而不是标准的 Spring MVC@Controller@RestController. 注解为@RepositoryRestController从 中定义的 API 基本路径提供RepositoryRestConfiguration.setBasePath,它由所有其他 RESTful 端点(例如/api). 以下示例演示如何使用@RepositoryRestController注解:spring-doc.cadn.net.cn

@RepositoryRestController
class ScannerController {

  private final ScannerRepository repository;

  ScannerController(ScannerRepository repository) { (1)
    this.repository = repository;
  }

  @GetMapping(path = "/scanners/search/producers") (2)
  ResponseEntity<?> getProducers() {

    List<String> producers = repository.listProducers(); (3)

    // do some intermediate processing, logging, etc. with the producers

    CollectionModel<String> resources = CollectionModel.of(producers); (4)

    resources.add(linkTo(methodOn(ScannerController.class).getProducers()).withSelfRel()); (5)

    // add other links as needed

    return ResponseEntity.ok(resources); (6)
  }
}
1 此示例使用构造函数注入。
2 此处理程序将自定义处理程序方法作为查询方法资源插入
3 此处理程序使用底层存储库来获取数据,但在将最终数据集返回给客户端之前,会进行某种形式的后处理。
4 类型 T 的结果需要封装在 Spring HATEOAS 中CollectionModel<T>object 返回一个集合。EntityModel<T>RepresentationModel<T>分别是适用于单个项目的包装器。
5 将链接添加回此确切方法的链接作为self链接。
6 使用 Spring MVC 的ResponseEntitywrapper 确保集合被正确包装并以正确的 accept 类型呈现。

CollectionModel用于集合,而EntityModel— 或更通用的类RepresentationModel— 用于单个项目。这些类型可以组合使用。如果您知道集合中每个项目的链接,请使用CollectionModel<EntityModel<String>>(或者任何核心域类型,而不是String).这样做可以为每个项目以及整个集合组合链接。spring-doc.cadn.net.cn

在此示例中,组合路径为RepositoryRestConfiguration.getBasePath() + /scanners/search/producers.

获取聚合引用

对于接收PUTPOSTrequests 的请求,则请求正文通常包含一个 JSON 文档,该文档将使用 URI 来表示对其他资源的引用。 为GETrequests 时,这些引用是通过 request 参数提交的。spring-doc.cadn.net.cn

从 Spring Data REST 4.1 开始,我们提供AggregateReference<T, ID>用作处理程序方法参数类型,以捕获此类引用并将其解析为引用的聚合的标识符、聚合本身或 jMoleculesAssociation. 您需要做的就是声明一个@RequestParam,然后使用标识符或完全解析的聚合。spring-doc.cadn.net.cn

@RepositoryRestController
class ScannerController {

  private final ScannerRepository repository;

  ScannerController(ScannerRepository repository) {
    this.repository = repository;
  }

  @GetMapping(path = "/scanners")
  ResponseEntity<?> getProducers(
    @RequestParam AggregateReference<Producer, ProducerIdentifier> producer) {

    var identifier = producer.resolveRequiredId();
    // Alternatively
    var aggregate = producer.resolveRequiredAggregate();
  }

  // Alternatively

  @GetMapping(path = "/scanners")
  ResponseEntity<?> getProducers(
    @RequestParam AssociationAggregateReference<Producer, ProducerIdentifier> producer) {

    var association = producer.resolveRequiredAssociation();
  }
}

如果您使用的是 jMolecules,AssociationAggregateReference还允许您获取Association. 虽然这两个抽象都假定参数的值是与 Spring Data REST 用于公开 item 资源的方案匹配的 URI,但可以通过调用….withIdSource(…)在引用实例上,提供一个函数来提取最终用于聚合解析的 identifier 值UriComponents从收到的 URI 获取。spring-doc.cadn.net.cn

@RepositoryRestController与。@BasePathAwareController

如果您对特定于实体的作不感兴趣,但仍想在下面构建自定义作basePath,例如 Spring MVC 视图、资源和其他视图,使用@BasePathAwareController. 如果您使用的是@RepositoryRestController在您的自定义控制器上,它只会在您的请求映射混合到存储库使用的 URI 空间时处理请求。 它还会将以下额外功能应用于控制器方法:spring-doc.cadn.net.cn

  1. 根据存储库的定义进行 CORS 配置,该存储库映射到处理程序方法的请求映射中使用的基本路径段。spring-doc.cadn.net.cn

  2. 应用OpenEntityManagerInViewInterceptor如果使用 JPA,则确保您可以访问标记为 to be resolved lazily 的属性。spring-doc.cadn.net.cn

如果您使用@Controller@RestController对于任何代码,该代码都完全超出了 Spring Data REST 的范围。这扩展到请求处理、消息转换器、异常处理和其他用途。