Java
函数计算支持使用Java进行编程,支持以下Java运行环境
- OpenJDK 1.8.0
Java语言由于需要编译以后才可以在JVM虚拟机中运行,因此CFC不支持在线编辑代码,仅仅支持通过web页面上传编译好的zip包和从BOS上传zip包两种方式上传代码。
当前CFC的Java运行时支持两种事件模式,点击下面链接您可以快速查看两种模式的简单开发示例
简单示例(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/
配置函数
创建函数时使用如下配置:
- 在函数管理页面,点击“创建函数”,进入创建函数页面。
- 填写您的函数名称等基本信息,运行时选择"java8",点击 提交。
- 在创建成功页面,选择进入代码编辑页面
- 选择"上传.zip文件",将上一步中压缩生成的zip文件上传至百度云。
- 处理程序中填写函数入口类名称,本例中为
com.baidu.demo.SimpleHandler
。
进阶用法(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();
}
}
代码示例
- 本章节中举例的Event模式的简单示例,请点击下载 简单示例
- 本章节中举例的Stream模式示例,请点击下载使用Stream模式
- 本章节中举例的log4j输出日志示例,请点击下载 使用log4j输出日志