Java
所有文档
menu

函数计算 CFC

Java

产品详情立即开通

函数计算支持使用Java进行编程,支持以下Java运行环境

  • OpenJDK 1.8.0

Java语言由于需要编译以后才可以在JVM虚拟机中运行,因此CFC不支持在线编辑代码,仅仅支持通过web页面上传编译好的zip包和从BOS上传zip包两种方式上传代码。

当前CFC的Java运行时支持两种事件模式,点击下面链接您可以快速查看两种模式的简单开发示例

  • event模式:所有触发器类型均支持该模式
  • stream模式:如果触发器类型是HTTP触发器,还支持stream模式

简单示例(event事件模式)

环境准备

确保您已经安装了JAVA和Maven。

创建项目

本示例使用开源Java项目管理工具Maven进行管理, 使用mvn命令行工具创建了一个groupId为com.baidu.demo,artifactId为bce-cfc-java-demo简单函数项目。, 命令如下。

$ mvn archetype:generate \
  -DgroupId=com.baidu.demo \
  -DartifactId=bce-cfc-java-demo \
  -Dversion=1.0 \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DinteractiveMode=no

运行完成之后,执行 tree 命令查看目录结构,应该是这样的

.
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── baidu
    │               └── demo
    │                   └── App.java
    └── test
        └── java
            └── com
                └── baidu
                    └── demo
                        └── AppTest.java

11 directories, 3 files

编写代码

在使用 Java 编程时,您首先需要定义一个函数入口类。创建文件 src/main/java/com/baidu/demo/SimpleHandler.java,写入以下内容,以下是一个最简单的入口函数:

package com.baidu.demo;

import com.baidubce.cfc.core.CfcContext;
import com.baidubce.cfc.core.StreamHandler;

import java.io.InputStream;
import java.io.OutputStream;

public class SimpleHandler implements StreamHandler {
    @Override
    public void handler(InputStream input, OutputStream output, CfcContext context) throws Exception {
        System.out.println("console outlog");
        System.err.println("console errlog");
        output.write("hello world!".getBytes());
    }
}

一些说明:

  • 函数入口类需要继承并实现com.baidubce.cfc.core.StreamHandler接口,该接口包含一个handler函数,handler函数有三个参数:

    • input表示输入数据
    • output表示输出数据
    • context表示函数运行时信息,使用context需要在代码中导入"com.baidubce.cfc.core.CfcContext"
  • 日志输出到stdout和stderr,函数计算服务会自动收集这些日志。

打开文件src/main/java/com/baidu/demo/App.java,写入以下内容:

package com.baidu.demo;

import com.baidubce.cfc.core.CfcClient;

public class App
{
    public static void main(String args[])
    {
        CfcClient.main(args);
    }
}

main入口函数中调用CfcClient.main进入函数运行时执行

maven编译并打包函数代码

在项目文件夹根目录创建pom.xml编译文件,可以在通过编辑pom.xml增加依赖和plugin配置, 以下分别给出示例

增加依赖:

函数计算相关接口定义于cfc-java-core包中,可以通过在pom.xml中增加以下 pom 定义引入该包依赖。在 <dependencies> 标签下加入这一段:

<dependency>
    <groupId>com.baidu.cfc</groupId>
    <artifactId>cfc-java-core</artifactId>
    <version>2.1.3</version>
</dependency>

增加 plugin 配置

在 pom.xml文件中添加 maven-assembly-plugin,构建一个可执行jar包。添加maven-dependency-plugin,将jar包所依赖的其他jar包拷贝至${project.build.directory}/lib目录。 在 project 标签下增加如下的两项:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.1.1</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/lib</outputDirectory>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.0.2</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>com.baidu.demo.App</mainClass>
                        <useUniqueVersions>false</useUniqueVersions>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

发布

// 打包
$ mvn clean package

// zip压缩
$ cd target
$ zip -r bce-cfc-java-demo.zip bce-cfc-java-demo-1.0.jar lib/

配置函数

创建函数时使用如下配置:

  1. 在函数管理页面,点击“创建函数”,进入创建函数页面。
  2. 填写您的函数名称等基本信息,运行时选择"java8",点击 提交image.png
  3. 在创建成功页面,选择进入代码编辑页面 image.png
  4. 选择"上传.zip文件",将上一步中压缩生成的zip文件上传至百度云。
  5. 处理程序中填写函数入口类名称,本例中为com.baidu.demo.SimpleHandlerimage.png

进阶用法(stream模式)

特别地,对于http trigger请求,除了可以使用普通的event模式进行处理外,还可以使用stream模式进行处理。在stream模式下,将启动一个http server接收并处理http trigger请求。

创建函数

与普通event模式不同,需要将事件模式设置为stream

编辑代码

下面显示了一个使用stream模式处理http trigger请求的例子,项目名称为httptrigger-demo。您首先需要定义一个函数入口类Demo, 需要继承并实现com.baidubce.cfc.core.http.HttpRequestHandler接口, 接口包含一个函数handleRequest,该函数包含三个参数 handler函数有三个参数:

  • request表示请求
  • response表示响应
  • context表示函数运行时信息,使用context需要在代码中导入"com.baidubce.cfc.core.CfcContext"
package com.baidubce.httptrigger.demo;

import com.baidubce.cfc.core.http.CfcContext;
import com.baidubce.cfc.core.http.HttpRequestHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.Logger;

public class Demo implements HttpRequestHandler {
    Logger logger =  Logger.getLogger("java.util.logging.ConsoleHandler");

    public void handleRequest(HttpServletRequest request,
                              HttpServletResponse response,
                              CfcContext context) throws ServletException, IOException {
        logger.info(String.format("requestid=%s", context.getRequestId()));
        logger.info(String.format("appid=%s", context.getApiID()));
        logger.info(String.format("clientip=%s", context.getClientIP()));
        response.getOutputStream().print("hello world!");
    }
}

因为该模式使用jetty, java runtime已经集成main函调用,无需单独写main调用cfcclient.main。

maven打包函数代码

添加依赖。

与event模式不同,stream模式依赖bce-cfc-java-httpcore包。

<dependencies>
    <dependency>
        <groupId>com.baidubce.cfc</groupId>
        <artifactId>bce-cfc-java-httpcore</artifactId>
        <version>1.0.0</version>
    </dependency>
</dependencies>

添加 plugin配置。

在package阶段增加了copy-dependencies功能,它将函数依赖的所有jar包拷贝到target/lib目录。同时,设置入口点mainClass为com.baidubce.cfc.core.http.CfcClient

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.1.1</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/lib</outputDirectory>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.0.2</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>com.baidubce.cfc.core.http.CfcClient</mainClass>
                        <useUniqueVersions>false</useUniqueVersions>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

打包

$ cd target/
$ zip -r httptrigger-demo.zip httptrigger-demo-1.0.0.jar lib/

上传代码

在函数编辑页面上传代码,步骤与普通event模式上传方式相同

处理POJO

除了StreamHandler外,运行时还支持直接处理POJO,可以通过实现RequestHandler<REQ, RSP>接口处理POJO。 支持的类型有:String,Integer,Boolean和其他可通过json序列化的自定义类型。

日志

使用Logger输出日志

创建logger配置文件

创建logger配置文件 src/main/resources/logger.properties

handlers = java.util.logging.ConsoleHandler

java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

初始化并使用logger

package com.baidu.demo;

import com.baidubce.cfc.core.CfcContext;
import com.baidubce.cfc.core.StreamHandler;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class DemoHandler implements StreamHandler {
 static {
       try{
        InputStream input = DemoHandler.class.getResourceAsStream("/logger.properties");
            LogManager.getLogManager().readConfiguration(input);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    Logger logger = Logger.getLogger(DemoHandler.class);
    public void handler(InputStream input, OutputStream output, CfcContext context) throws Exception {
       logger.info("info log");
       logger.warning("warn log");
       output.write("hello world!".getBytes());
    }
}

使用log4j输出日志

增加依赖:

在pom.xml文件中,> 标签下加入这一段:

<dependency>
	<groupId>log4j</groupId>
	<artifactId>log4j</artifactId>
	<version>1.2.17</version>
</dependency>

配置log4j

创建配置文件src/main/resources/log4j.properties

log4j.rootLogger = debug,stdout

### 输出信息到控制台 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

代码中使用log4j

package com.baidu.demo.log4j;

import com.baidubce.cfc.core.StreamHandler;
import org.apache.log4j.Logger;
import com.baidubce.cfc.core.CfcContext;
import com.baidubce.cfc.core.StsCredential;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;

public class DemoHandler  implements StreamHandler {
    Logger logger = Logger.getLogger(DemoHandler.class);

    public DemoHandler() {
    }

    public void handler(InputStream input, OutputStream output, CfcContext context) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        InvokeEvent event = mapper.readValue(input, InvokeEvent.class);
        if (event.getEvent() != null) {
            logger.info(event.getEvent());
        }

        PrintStream stream = new PrintStream(output);
        stream.println("Hello world");
        stream.close();
    }
}

代码示例

上一篇
Golang
下一篇
C#