您可以使用Java請求處理常式響應接收到的事件並執行相應的商務邏輯。本文介紹Java請求處理常式的相關概念、結構特點和樣本。
如您需要通過HTTP觸發器或自訂網域名訪問函數,請先擷取請求結構體再自訂HTTP響應。更多資訊,請參見HTTP觸發器調用函數。
什麼是請求處理常式
FC函數的請求處理常式,是函數代碼中處理請求的方法。當您的函數被調用時,Function Compute會運行您提供的Handler方法處理請求。
您可以通過Function Compute控制台配置請求處理常式,對於Java語言的函數,您的請求處理常式需配置為[包名].[類名]::[方法名]
。例如,您的包名為example,類型為HelloFC,方法名為handleRequest,則請求處理常式可配置為example.HelloFC::handleRequest
。
請求處理常式的具體配置均需符合Function Compute平台的配置規範。配置規範因請求處理常式類型而異。
處理常式介面
您在使用Java編程時,必須要實現Function Compute提供的介面類,fc-java-core庫為請求處理常式定義了以下兩個介面。
以流的方式接收輸入的
event
事件並返回執行結果。您需要從輸入資料流中讀取調用函數時的輸入,處理完成後把函數執行結果寫到輸出資料流中來返回。以泛型的方式接收輸入的
event
事件並返回執行結果。您可以自訂輸入和輸出的類型,但是輸入和輸出的類型必須是POJO類型。
StreamRequestHandler
一個最簡單的StreamRequestHandler樣本如下所示。
package example;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.StreamRequestHandler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class HelloFC implements StreamRequestHandler {
@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
outputStream.write(new String("hello world").getBytes());
}
}
包名和類名
由於Java有包的概念,因此執行方法和其他語言有所不同,需要包含包的資訊。程式碼範例中請求處理常式(handler)為
example.HelloFC::handleRequest
,其中example
標識為包名,HelloFC
標識為類名,handleRequest
標識為類方法。說明包名和類名可以是任意的,但是需要與函數配置資訊中的請求處理常式欄位相對應。關於請求處理常式的設定,請參見建立事件函數。
實現的介面
您的代碼中必須要實現Function Compute預定義的介面。上述的程式碼範例中實現了
StreamRequestHandler
,其中的inputStream參數為調用函數時傳入的資料,outputStream參數用於返回函數的執行結果。Context參數
Context參數中包含一些函數的運行時資訊(例如RequestId、臨時AccessKey等),其類型是
com.aliyun.fc.runtime.Context
。具體資訊,請參見上下文。傳回值
實現
StreamRequestHandler
介面的函數通過outputStream
參數返回執行結果。引入介面庫
其中用到的
com.aliyun.fc.runtime
包的依賴可以通過下文的pom.xml
引用。<dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-core</artifactId> <version>1.4.1</version> </dependency>
您可以通過Maven倉庫擷取
fc-java-core
最新的版本號碼。
在建立函數之前,您需要將代碼和其依賴的fc-java-core
打包為JAR格式的壓縮包。打包方式,請參見編譯部署程式碼封裝。
PojoRequestHandler
一個最簡單的PojoRequestHandler樣本如下所示。SimpleRequest的對象需要支援JSON序列化,例如POJO。
// HelloFC.java
package example;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.PojoRequestHandler;
public class HelloFC implements PojoRequestHandler<SimpleRequest, SimpleResponse> {
@Override
public SimpleResponse handleRequest(SimpleRequest request, Context context) {
String message = "Hello, " + request.getFirstName() + " " + request.getLastName();
return new SimpleResponse(message);
}
}
// SimpleRequest.java
package example;
public class SimpleRequest {
String firstName;
String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public SimpleRequest() {}
public SimpleRequest(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
// SimpleResponse.java
package example;
public class SimpleResponse {
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public SimpleResponse() {}
public SimpleResponse(String message) {
this.message = message;
}
}
傳入的event參數樣本如下。
{
"firstName": "FC",
"lastName": "aliyun"
}
樣本:使用HTTP觸發器調用函數
範例程式碼
以上範例程式碼中,HTTPTriggerEvent.java聲明了HTTP觸發器的請求格式,HTTPTriggerResponse.java聲明了HTTP觸發器的響應格式,關於HTTP觸發器的請求結構體和響應結構體的詳細格式,請參見HTTP觸發器調用函數。
App.java定義了函數入口類。
本樣本程式除了引入fc-java-core庫外,還需要引入jackson和lombok兩個庫,可以在Maven的設定檔pom.xml
中添加此依賴。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
前提條件
已使用上述樣本建立運行環境為Java的函數,並建立HTTP觸發器。具體操作,請參見建立事件函數和配置HTTP觸發器並使用HTTP觸發。
操作步驟
登入Function Compute控制台,在左側導覽列,單擊函數。
在頂部功能表列,選擇地區,然後在函數頁面,單擊目標函數。
在函數詳情頁面,單擊觸發器管理頁簽,擷取HTTP觸發器的公網訪問地址。
在Curl工具執行以下命令,調用函數。
curl -i "https://dev-jav-test-fc-luiqas****.cn-shanghai.fcapp.run" -d 'hello fc3.0'
以上命令中,
https://dev-jav-test-fc-luiqas****.cn-shanghai.fcapp.run
為擷取到的HTTP觸發器公網訪問地址。響應結果如下。
HTTP/1.1 200 OK Content-Disposition: attachment Content-Length: 11 Content-Type: application/json X-Fc-Request-Id: 1-652503f2-afbfd2b1dc4dd0fcb0230959 Date: Tue, 10 Oct 2023 07:57:38 GMT hello fc3.0%
錯誤分析
本範例程式碼支援使用HTTP觸發器或者自訂網域名調用。如果使用API調用,但配置的測試參數不符合HTTP觸發器請求格式規範時,會出現報錯。
例如,在控制台上調用函數,配置請求參數為"Hello, FC!"
,單擊測試函數,收到的響應如下所示。
{
"errorType": "com.fasterxml.jackson.databind.exc.MismatchedInputException",
"errorMessage": "Cannot construct instance of `example.HTTPTriggerEvent` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('Hello, FC!')\n at [Source: (byte[])\"\"Hello, FC!\"\"; line: 1, column: 1]",
"stackTrace": [
"com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)",
"com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1588)",
"com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1213)",
"com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromString(StdDeserializer.java:311)",
"com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1495)",
"com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:207)",
"com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:197)",
"com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)",
"com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)",
"com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3643)"
]
}
樣本程式
Function Compute官方庫包含了使用各種處理常式類型和介面的應用程式範例。每個應用程式範例都包含用於輕鬆編譯部署的方法。例如:
java11-blank-stream-event:使用Stream格式的事件回調處理常式。
java11-blank-pojo-event:使用POJO格式的事件回調處理常式。