覆蓋 Spring Data REST 響應處理器

有時,您可能希望為特定資源編寫一個自定義處理器。為了利用Spring Data REST的設定、訊息轉換器、異常處理等,請使用@RepositoryRestController註解,而不是標準的Spring MVC @Controller@RestController。帶有@RepositoryRestController註解的控制器將從RepositoryRestConfiguration.setBasePath中定義的API基路徑提供服務,所有其他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> 物件中才能返回集合。EntityModel<T>RepresentationModel<T> 分別適用於單個專案的包裝器。
5 新增一個連結回此確切方法作為 self 連結。
6 透過使用Spring MVC的ResponseEntity包裝器返回集合,可以確保集合被正確包裝並以適當的接受型別呈現。

CollectionModel 用於集合,而 EntityModel — 或更通用的類 RepresentationModel — 用於單個專案。這些型別可以組合。如果您知道集合中每個專案的連結,請使用 CollectionModel<EntityModel<String>>(或核心領域型別,而不是 String)。這樣做可以為每個專案以及整個集合組裝連結。

在此示例中,組合路徑是 RepositoryRestConfiguration.getBasePath() + /scanners/search/producers

獲取聚合引用

對於接收 PUTPOST 請求的自定義控制器,請求正文通常包含一個 JSON 文件,該文件將使用 URI 來表示對其他資源的引用。對於 GET 請求,這些引用透過請求引數傳遞。

從 Spring Data REST 4.1 開始,我們提供 AggregateReference<T, ID> 作為處理程式方法引數型別,用於捕獲此類引用並將其解析為引用的聚合識別符號、聚合本身或 jMolecules Association。您只需宣告一個該型別的 @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(…) 來定製該源值解析,以提供一個函式,從收到的 URI 獲取的 UriComponents 中提取最終用於聚合解析的識別符號值。

@RepositoryRestController@BasePathAwareController

如果您對實體特定的操作不感興趣,但仍希望在 basePath 下構建自定義操作,例如 Spring MVC 檢視、資源等,請使用 @BasePathAwareController。如果您在自定義控制器上使用 @RepositoryRestController,則只有當您的請求對映與儲存庫使用的 URI 空間融合時,它才會處理請求。它還會為控制器方法應用以下額外功能。

  1. 根據為對映到處理程式方法請求對映中使用的基本路徑段的儲存庫定義的 CORS 配置。

  2. 如果使用 JPA,則應用 OpenEntityManagerInViewInterceptor,以確保您可以訪問標記為延遲解析的屬性。

如果您將 @Controller@RestController 用於任何目的,該程式碼完全在 Spring Data REST 的範圍之外。這包括請求處理、訊息轉換器、異常處理和其他用途。
© . This site is unofficial and not affiliated with VMware.