領先一步
VMware 提供訓練和認證,以加速您的進展。
了解更多本系列文章從介紹基於 Java 函式的全新串流應用程式開始,以及函式組合。前一篇條目介紹了如何建構簡單串流應用程式並在 Spring Cloud Data Flow 中執行。今天我們將探討 HTTP 請求函式,並展示如何使用它的範例。
如果您錯過了,本系列先前的文章包括
這是基於反應式 Spring WebClient 的舊版 HTTP Client Processor Stream App Starter 的更新實作。此函式是通用的 Web 用戶端,可將 HTTP 請求提交到 URL 並傳回回應。專為串流應用程式設計,它能夠使用針對每個傳入訊息評估的已配置 SpEL 表達式,提取 URL、HTTP 方法、請求 body、所需的回應類型和內容。此外,為了支援高效的串流處理,此函式使用反應式串流。其簽章為
Function<Flux<Message>, Flux>
也就是說,它接受訊息的 Flux(串流)並傳回任何類型的 Flux。
HttpRequestFunction 透過以下配置屬性進行配置
http.request.body-expression
用於從傳入訊息衍生請求 body 的 SpEL 表達式。(表達式,預設值
http.request.expected-response-type
用於解譯回應的類型。(Class<?>,預設值:String)
http.request.headers-expression
用於衍生要使用的 http headers 對應的 SpEL 表達式。(表達式,預設值
http.request.http-method-expression
用於從傳入訊息衍生請求方法的 SpEL 表達式。(表達式,預設值:GET)
http.request.maximum-buffer-size
為輸入串流緩衝區配置的最大緩衝區大小(以位元組為單位)。預設值為 256k。如有必要,請增加此值以張貼或取得大型二進位內容。(Integer,預設值:256 * 1024)
http.request.reply-expression
用於計算最終結果的 SpEL 表達式,應用於整個 http {@link org.springframework.http.ResponseEntity}。(表達式,預設值:ResponseEntity::getBody)
http.request.timeout
請求逾時時間(毫秒)。(Long,預設值:30000)
http.request.url-expression
針對傳入訊息以判斷要使用的 URL 的 SpEL 表達式。(表達式,預設值
SpEL 表達式會應用於傳入的訊息。因此,可以使用 body
和 headers[name]
等欄位來評估訊息內容。我說「可以使用…」,因為有時使用靜態值更為理想。在這種情況下,常值必須以單引號括起來,例如
http.request.url-expression='https://start.spring.io' http.request.http-method-expression='POST'
讓我們來看一個範例,說明如何在簡單的 Spring Boot 網路應用程式中使用此函式。在此範例中,我們將在一個應用程式中使用它,該應用程式從 URL 檢索影像並呈現影像的縮圖。此範例的完整程式碼在此處。
我們將使用 Spring Boot 和 Spring Web Flux 建構應用程式,以及我們的函式來檢索影像,以及一些程式碼來產生縮圖。
相關的依賴項包括
org.springframework.cloud.fn:http-request-function - HTTP 請求函式會間接包含 spring-boot-starter-webflux
io.spring.example:image-thumbnail-processor - 一個簡單的 Java 函式,包含在此範例中,用於建立縮圖。我們在此不深入探討細節,僅請注意,這是一個獨立的元件,我們將在稍後的範例中重複使用。
我們首先需要為我們的函式設定一些配置屬性
http.request.url-expression=payload http.request.expected-response-type=byte[] http.request.maximum-buffer-size=2097152
因此,訊息 payload 包含目標 URL,影像(回應 body)將以位元組陣列形式傳回。由於這些影像可能相當大,我們將把保存回應 body 的緩衝區大小增加到 2GB (2 * 1024 * 1024)。
程式碼如下
@SpringBootApplication
@Controller
@Import(HttpRequestFunctionConfiguration.class)
public class ThumbnailStandaloneApplication {
private static Logger logger = LoggerFactory.getLogger(ThumbnailStandaloneApplication.class);
public static void main(String[] args) {
SpringApplication.run(ThumbnailStandaloneApplication.class, args);
}
private ThumbnailProcessor thumbnailProcessor = new ThumbnailProcessor();
@Autowired
private HttpRequestFunction httpRequestFunction;
@Bean
RouterFunction<?> routes() {
return RouterFunctions.route()
.GET("/thumbnail", this::createThumbnail)
.build();
}
private Mono<ServerResponse> createThumbnail(ServerRequest serverRequest) {
String url = serverRequest.queryParam("url").orElseThrow(
() -> new RuntimeException("URL required"));
return Mono.from(httpRequestFunction.apply(Flux.just(new GenericMessage<>(url)))
.flatMap(image -> {
Map<String, Object> model = new HashMap<>();
byte[] thumbnail = thumbnailProcessor.apply((byte[]) image);
logger.info("creating thumbnail for {}", url);
model.put("url", url);
model.put("thumb", new String(Base64.getEncoder().encode(thumbnail)));
Mono<ServerResponse> serverResponse = ServerResponse.ok()
.render("thumbnail", model);
return serverResponse;
}));
}
我們應用 HttpRequestFunction
來檢索影像。然後我們將 thumbnailProcessor
應用於傳回的位元組陣列,並將其編碼為 base 64,以便我們可以在頁面上呈現它。
現在我們了解函式如何運作,讓我們使用 Spring Cloud Stream 組建一個串流應用程式來執行類似的操作。在此案例中,我們將使用預先封裝的 HTTP 請求處理器和 File Source 串流應用程式。此處理器將 HTTP 請求函式包裝在 Spring Cloud Stream 處理器應用程式中,該應用程式僅調用該函式,將輸入和輸出繫結到訊息代理目的地(例如 Kafka 主題或 Rabbit MQ 交換器)。我們的應用程式以串流定義 DSL 表示,如下所示
file-source | http-request-processor | image-thumbnail-sink
其中 |
表示使用訊息代理的 I/O。
在此,我們使用使用者開發的接收器,該接收器使用 file-consumer 函式將每個縮圖寫入檔案。此接收器使用 Spring Cloud Function 的宣告式組合,將前一個範例中的 thumbnail-processor 與標頭豐富器以及最終的標準 fileConsumer 組合在一起。因此,我們的組合函式由以下項目定義
spring.cloud.function.definition=thumbnailProcessor|filenameEnricher|fileConsumer
我們的複合函式定義在概念上和語法上與上述串流定義相似。但在這種情況下,|
表示程序內通訊。
我們將在未來的文章中探討 File Source 的來龍去脈。目前,我們將使用它來輪詢來源目錄,並在每次將新檔案新增至目錄時產生訊息。在此案例中,我們想要處理每行包含一個影像 URL 的文字檔。我們將配置來源以產生每行一個訊息,其中包含 payload 中的 URL。我們已經知道 HTTP 請求處理器的作用。接收器產生縮圖並將其寫入檔案。
完全配置的串流定義如下
file-source --file.consumer.mode=lines --file.consumer.mode=lines --file.supplier.directory=
如果我們執行此操作並將文字檔放入來源目錄,我們將看到縮圖寫入目標目錄
如果您想在您的本機電腦上執行此操作,完整的說明在此處。
我們剛剛深入探討了 HTTP 請求函式,示範如何在獨立網路應用程式和串流管線中使用它來處理影像。我們還使用了函式組合,將使用者編寫的函式和現成的函式組合在一起,效果顯著。
在接下來的幾週內,我們將針對 Spring Cloud Stream 和 Spring Cloud Data Flow 推出更多案例研究,每個案例都將重點介紹不同的串流應用程式和功能。