|
此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Data REST 4.5.3! |
重写 Spring Data REST 响应处理程序
有时,您可能想要为特定资源编写自定义处理程序。
要利用 Spring Data REST 的设置、消息转换器、异常处理等,请使用@RepositoryRestController注释而不是标准的 Spring MVC@Controller或@RestController.
用@RepositoryRestController从RepositoryRestConfiguration.setBasePath,由所有其他 RESTful 端点(例如/api).
以下示例演示如何使用@RepositoryRestController注解:
@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).这样做可以让你为每个项目以及整个集合组装链接。
在此示例中,组合路径为RepositoryRestConfiguration.getBasePath() + /scanners/search/producers. |
获取聚合参考
对于接收的自定义控制器PUT和POST请求,请求正文通常包含一个 JSON 文档,该文档将使用 URI 来表达对其他资源的引用。
为GETrequests,这些引用是通过请求参数传递的。
从 Spring Data REST 4.1 开始,我们提供了AggregateReference<T, ID>用作处理程序方法参数类型,以捕获此类引用并将它们解析为引用聚合的标识符、聚合本身或 jMoleculesAssociation.
您需要做的就是声明一个@RequestParam,然后使用标识符或完全解析的聚合。
@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 用于公开项目资源的方案匹配的 URI,但可以通过调用….withIdSource(…)在引用实例上提供一个函数,以从UriComponents从收到的 URI 中获取。
@RepositoryRestController与。@BasePathAwareController
如果您对特定于实体的作不感兴趣,但仍想在下面构建自定义作basePath,例如 Spring MVC 视图、资源等,使用@BasePathAwareController.
如果您正在使用@RepositoryRestController在自定义控制器上,只有当您的请求映射混合到存储库使用的 URI 空间中时,它才会处理请求。
它还将以下额外功能应用于控制器方法:
-
根据映射到处理程序方法的请求映射中使用的基本路径段的存储库定义的 CORS 配置。
-
应用
OpenEntityManagerInViewInterceptor如果使用 JPA 来确保您可以访问标记为延迟解析的属性。
如果您使用@Controller或@RestController对于任何事情,该代码完全超出了 Spring Data REST 的范围。这扩展到请求处理、消息转换器、异常处理和其他用途。 |