在函数计算中使用 Java 编程,需要定义一个函数作为入口函数。为函数设置 HTTP 触发器后,可以方便处理发来的 HTTP 请求。

HTTP 函数接口

函数计算提供基于 Servlet 协议的 HTTP 入口,形式如下所示。

public interface HttpRequestHandler {
    /**
     * The entrance function of fc http trigger 
     * @param request The servlet request
     * @param response The servlet response
     * @param context The fc context
     * @throws IOException If IO exception happened
     * @throws ServletException If servlet exception happened
     */
    public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context) throws IOException, ServletException;
}      

使用 HTTP 触发器需要将 fc-java-core 库版本升级到 1.3.0 及以上。

HTTP 触发器的简单示例

package com.aliyun.fc.example;

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.HttpRequestHandler;

public class Hello implements HttpRequestHandler {
    public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context)
            throws IOException, ServletException {
        String requestPath = (String) request.getAttribute("FC_REQUEST_PATH");
        String requestURI = (String) request.getAttribute("FC_REQUEST_URI");
        String requestClientIP = (String) request.getAttribute("FC_REQUEST_CLIENT_IP"); 

        response.setStatus(200);
        response.setHeader("header1", "value1");
        response.setHeader("header2", "value2");

        String body = String.format("Path: %s\n Uri: %s\n IP: %s\n", requestPath, requestURI, requestClientIP);
        OutputStream out = response.getOutputStream();
        out.write((body).getBytes());
        out.flush();
        out.close();
    }
}          
  • HttpServletRequest

    函数计算 HTTP 触发器的接口使用标准的 Servlet 协议。您的请求会封装成 HttpServletRequest 对象,请求参数、请求头等均可通过此对象获取。除此之外,函数计算在 HttpServletRequest 中预封装了一些属性,您可以通过 getAttribute 方法来获取,具体包括:

    • FC_REQUEST_PATH:获取请求的路径。

    • FC_REQUEST_URI:获取请求的 URI。

    • FC_REQUEST_CLIENT_IP:获取请求的 Client IP 地址。

  • HttpServletResponse

    您可以通过标准的 HttpServletResponse 协议对象来返回响应头和响应体。

  • context 参数

    context 参数中包含一些函数的运行时信息(例如 Request ID、临时 AccessKey 等),其类型是 com.aliyun.fc.runtime.Context

HTTP 触发器支持传统 Web 应用

基于 Servlet 协议的传统 Web 应用能很方便地迁移到函数计算平台,目前支持的主流框架包括 Spring、SpringBoot、Struts2 等。以下示例演示了如何通过函数计算提供的 fc-java-common 库来加载 Web 应用。

  1. 打包您的 Web 工程,生成 demo.war
  2. 上传 demo.war 包到 OSS,例如上传到 demo-bucket 目录下。
  3. 创建函数,并设置函数 Initializer 入口和入口函数。
    • 函数示例代码如下。

      package com.aliyun.fc.example;
      
      import java.io.IOException;
      
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      import com.aliyun.fc.runtime.Context;
      import com.aliyun.fc.runtime.FcAppLoader;
      import com.aliyun.fc.runtime.FunctionComputeLogger;
      import com.aliyun.fc.runtime.FunctionInitializer;
      import com.aliyun.fc.runtime.HttpRequestHandler;
      
      public class HelloWeb implements FunctionInitializer, HttpRequestHandler {
        private FcAppLoader fcAppLoader = new FcAppLoader();
      
        private String ossEndPoint = "YourOSSEndPoint";
        private String bucket = "YourOSSBucket";
        private String key = "YourWarName";
        private String userContextPath = "/2016-08-15/proxy/{YourServiceName}/{YourFunctionName}";
      
        @Override
        public void initialize(Context context) throws IOException {
              FunctionComputeLogger fcLogger = context.getLogger();
      
              fcAppLoader.setFCContext(context);
      
              // Load code from OSS
              fcAppLoader.loadCodeFromOSS(ossEndPoint, bucket, key);
      
              // Init webapp from code
              fcAppLoader.initApp(userContextPath, HelloWeb.class.getClassLoader());
        }
      
        @Override
        public void handleRequest(HttpServletRequest request, HttpServletResponse response, Context context)
                  throws IOException, ServletException {
              try {
                  fcAppLoader.forward(request, response);
              } catch (Exception e) {
                  e.printStackTrace();
              }
        }
      }                            
    • 引用 Maven 库

       <dependency>
            <groupId>com.aliyun.fc.runtime</groupId>
            <artifactId>fc-java-core</artifactId>
            <version>1.3.0</version>
        </dependency>
      
        <dependency>
            <groupId>com.aliyun.fc.runtime</groupId>
            <artifactId>fc-java-common</artifactId>
            <version>2.2.2</version>
        </dependency>                  

更多信息

HTTP 触发器的使用,请参见 HTTP 触发器