搶佔先機
VMware 提供培訓和認證,助您加速前進。
瞭解更多我們以介紹新的基於 Java 函式的流應用以及函式組合來開始本系列。上一篇提供了一個教程,介紹如何構建簡單的流應用並在 Spring Cloud Data Flow 中執行。今天我們探索HTTP 請求函式並提供如何使用它的示例。
如果您錯過了,本系列之前的文章如下
這是遺留的HTTP Client Processor流應用 Starter 的更新實現,基於響應式的 Spring WebClient。該函式是一個通用的 web 客戶端,向 URL 提交 HTTP 請求並返回響應。它主要為流應用設計,能夠使用根據每條輸入 Message 評估的配置的SpEL 表示式來提取 URL、HTTP 方法、請求體、期望的響應型別和內容。此外,為了支援高效的流處理,該函式使用了 reactive streams。其簽名是
Function<Flux<Message>, Flux>
>>也就是說,它接受一個Flux (流) 的 Messages,並返回一個任何型別的 Flux。
HttpRequestFunction 透過以下配置屬性進行配置
http.request.body-expression
用於從輸入訊息中派生請求體的 SpEL 表示式。(表示式,預設值
http.request.expected-response-type
用於解釋響應的型別。(Class<?>,預設值:String)
http.request.headers-expression
用於派生要使用的 http headers map 的 SpEL 表示式。(表示式,預設值
http.request.http-method-expression
用於從輸入訊息中派生請求方法的 SpEL 表示式。(表示式,預設值:GET)
http.request.maximum-buffer-size
為輸入流緩衝區分配的最大緩衝區大小(以位元組為單位)。預設為 256k。對於 posting 或 getting 大型二進位制內容,如有必要,請增大此值。(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 表示式應用於輸入 Message。因此,諸如 body
和 headers[name]
之類的欄位可用於評估訊息內容。我說“可以…”是因為有時使用靜態值更可取。在這種情況下,字面量值必須用單引號括起來,例如
http.request.url-expression='https://start.spring.io' http.request.http-method-expression='POST'
讓我們看看如何在簡單的 Spring Boot Web 應用中使用此函式的示例。在此示例中,我們將在一個應用中使用它,該應用從 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
因此,訊息有效載荷包含目標 URL,影像(響應體)將以位元組陣列形式返回。並且由於這些影像可能相當大,我們將把存放響應體的緩衝區大小增加到 2MB (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。
在這裡,我們使用了一個使用者開發的 sink,它使用file-consumer函式將每個縮圖寫入檔案。該 sink 使用 Spring Cloud Function 的宣告性組合,將上一示例中的thumbnail-processor與一個 header enricher 以及最後的標準fileConsumer進行組合。因此,我們組合的函式定義為
spring.cloud.function.definition=thumbnailProcessor|filenameEnricher|fileConsumer
我們的複合函式定義在概念和語法上與上述流定義相似。但在此示例中,|
表示程序內通訊。
我們將在未來的文章中探討 File Source 的詳細資訊。目前,我們將使用它來輪詢源目錄,並在目錄中新增新檔案時生成訊息。在此示例中,我們想要處理一個文字檔案,其中每行包含一個影像 URL。我們將配置源以每行生成一條訊息,訊息的有效載荷中包含 URL。我們已經知道 HTTP 請求處理器做什麼。sink 生成縮圖並將其寫入檔案。
完整配置的流定義如下
file-source --file.consumer.mode=lines --file.consumer.mode=lines --file.supplier.directory=
如果我們執行此應用並將一個文字檔案放入源目錄,我們將看到縮圖寫入目標目錄
如果您想在本地機器上執行此應用,完整的說明在此處。
我們剛才深入探討了 HTTP 請求函式,演示瞭如何在獨立 Web 應用和流式管道中使用它來處理影像。我們還使用了函式組合,將使用者編寫的函式與現成的函式進行組合,取得了很好的效果。
在接下來的幾周,我們將展示更多關於 Spring Cloud Stream 和 Spring Cloud Data Flow 的案例研究,每個案例都將重點介紹不同的流應用和功能。