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
简单函数项目,命令如下。
1$ mvn archetype:generate \
2 -DgroupId=com.baidu.demo \
3 -DartifactId=bce-cfc-java-demo \
4 -Dversion=1.0 \
5 -DarchetypeArtifactId=maven-archetype-quickstart \
6 -DinteractiveMode=no
运行完成之后,执行 tree
命令查看目录结构,应该是这样的
1.
2├── pom.xml
3└── src
4 ├── main
5 │ └── java
6 │ └── com
7 │ └── baidu
8 │ └── demo
9 │ └── App.java
10 └── test
11 └── java
12 └── com
13 └── baidu
14 └── demo
15 └── AppTest.java
16
1711 directories, 3 files
编写代码
在使用 Java 编程时,您首先需要定义一个函数入口类。创建文件 src/main/java/com/baidu/demo/SimpleHandler.java
,写入以下内容,以下是一个最简单的入口函数:
1package com.baidu.demo;
2
3import com.baidubce.cfc.core.CfcContext;
4import com.baidubce.cfc.core.StreamHandler;
5
6import java.io.InputStream;
7import java.io.OutputStream;
8
9public class SimpleHandler implements StreamHandler {
10 @Override
11 public void handler(InputStream input, OutputStream output, CfcContext context) throws Exception {
12 System.out.println("console outlog");
13 System.err.println("console errlog");
14 output.write("hello world!".getBytes());
15 }
16}
一些说明:
-
函数入口类需要继承并实现
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
,写入以下内容:
1package com.baidu.demo;
2
3import com.baidubce.cfc.core.CfcClient;
4
5public class App
6{
7 public static void main(String args[])
8 {
9 CfcClient.main(args);
10 }
11}
在main
入口函数中调用CfcClient.main
进入函数运行时执行
maven编译并打包函数代码
在项目文件夹根目录创建pom.xml编译文件,可以在通过编辑pom.xml增加依赖和plugin配置, 以下分别给出示例
增加依赖:
函数计算相关接口定义于cfc-java-core
包中,可以通过在pom.xml中增加以下 pom 定义引入该包依赖。在 <dependencies>
标签下加入这一段:
1<dependency>
2 <groupId>com.baidu.cfc</groupId>
3 <artifactId>cfc-java-core</artifactId>
4 <version>2.1.3</version>
5</dependency>
增加 plugin 配置
在 pom.xml文件中添加 maven-assembly-plugin,构建一个可执行jar包。添加maven-dependency-plugin,将jar包所依赖的其他jar包拷贝至${project.build.directory}/lib
目录。 在 project
标签下增加如下的两项:
1<properties>
2 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3 <maven.compiler.source>1.8</maven.compiler.source>
4 <maven.compiler.target>1.8</maven.compiler.target>
5</properties>
6<build>
7 <plugins>
8 <plugin>
9 <groupId>org.apache.maven.plugins</groupId>
10 <artifactId>maven-dependency-plugin</artifactId>
11 <version>3.1.1</version>
12 <executions>
13 <execution>
14 <id>copy-dependencies</id>
15 <phase>package</phase>
16 <goals>
17 <goal>copy-dependencies</goal>
18 </goals>
19 <configuration>
20 <outputDirectory>${project.build.directory}/lib</outputDirectory>
21 <overWriteReleases>false</overWriteReleases>
22 <overWriteSnapshots>false</overWriteSnapshots>
23 <overWriteIfNewer>true</overWriteIfNewer>
24 </configuration>
25 </execution>
26 </executions>
27 </plugin>
28 <plugin>
29 <!-- Build an executable JAR -->
30 <groupId>org.apache.maven.plugins</groupId>
31 <artifactId>maven-jar-plugin</artifactId>
32 <version>3.0.2</version>
33 <configuration>
34 <archive>
35 <manifest>
36 <addClasspath>true</addClasspath>
37 <classpathPrefix>lib/</classpathPrefix>
38 <mainClass>com.baidu.demo.App</mainClass>
39 <useUniqueVersions>false</useUniqueVersions>
40 </manifest>
41 </archive>
42 </configuration>
43 </plugin>
44 </plugins>
45</build>
发布
1// 打包
2$ mvn clean package
3
4// zip压缩
5$ cd target
6$ 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"
1package com.baidubce.httptrigger.demo;
2
3import com.baidubce.cfc.core.http.CfcContext;
4import com.baidubce.cfc.core.http.HttpRequestHandler;
5
6import javax.servlet.ServletException;
7import javax.servlet.http.HttpServletRequest;
8import javax.servlet.http.HttpServletResponse;
9import java.io.IOException;
10import java.util.logging.Logger;
11
12public class Demo implements HttpRequestHandler {
13 Logger logger = Logger.getLogger("java.util.logging.ConsoleHandler");
14
15 public void handleRequest(HttpServletRequest request,
16 HttpServletResponse response,
17 CfcContext context) throws ServletException, IOException {
18 logger.info(String.format("requestid=%s", context.getRequestId()));
19 logger.info(String.format("appid=%s", context.getApiID()));
20 logger.info(String.format("clientip=%s", context.getClientIP()));
21 response.getOutputStream().print("hello world!");
22 }
23}
因为该模式使用jetty, java runtime已经集成main函调用,无需单独写main调用cfcclient.main。
maven打包函数代码
添加依赖。
与event模式不同,stream模式依赖bce-cfc-java-httpcore
包。
1<dependencies>
2 <dependency>
3 <groupId>com.baidubce.cfc</groupId>
4 <artifactId>bce-cfc-java-httpcore</artifactId>
5 <version>1.0.0</version>
6 </dependency>
7</dependencies>
添加 plugin配置。
在package阶段增加了copy-dependencies功能,它将函数依赖的所有jar包拷贝到target/lib
目录。同时,设置入口点mainClass为com.baidubce.cfc.core.http.CfcClient
。
1<build>
2 <plugins>
3 <plugin>
4 <groupId>org.apache.maven.plugins</groupId>
5 <artifactId>maven-dependency-plugin</artifactId>
6 <version>3.1.1</version>
7 <executions>
8 <execution>
9 <id>copy-dependencies</id>
10 <phase>package</phase>
11 <goals>
12 <goal>copy-dependencies</goal>
13 </goals>
14 <configuration>
15 <outputDirectory>${project.build.directory}/lib</outputDirectory>
16 <overWriteReleases>false</overWriteReleases>
17 <overWriteSnapshots>false</overWriteSnapshots>
18 <overWriteIfNewer>true</overWriteIfNewer>
19 </configuration>
20 </execution>
21 </executions>
22 </plugin>
23 <plugin>
24 <!-- Build an executable JAR -->
25 <groupId>org.apache.maven.plugins</groupId>
26 <artifactId>maven-jar-plugin</artifactId>
27 <version>3.0.2</version>
28 <configuration>
29 <archive>
30 <manifest>
31 <addClasspath>true</addClasspath>
32 <classpathPrefix>lib/</classpathPrefix>
33 <mainClass>com.baidubce.cfc.core.http.CfcClient</mainClass>
34 <useUniqueVersions>false</useUniqueVersions>
35 </manifest>
36 </archive>
37 </configuration>
38 </plugin>
39 </plugins>
40</build>
打包
1$ cd target/
2$ 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
1handlers = java.util.logging.ConsoleHandler
2
3java.util.logging.ConsoleHandler.level=INFO
4java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
初始化并使用logger
1package com.baidu.demo;
2
3import com.baidubce.cfc.core.CfcContext;
4import com.baidubce.cfc.core.StreamHandler;
5
6import java.io.InputStream;
7import java.io.OutputStream;
8import java.util.logging.LogManager;
9import java.util.logging.Logger;
10
11public class DemoHandler implements StreamHandler {
12 static {
13 try{
14 InputStream input = DemoHandler.class.getResourceAsStream("/logger.properties");
15 LogManager.getLogManager().readConfiguration(input);
16 }catch (Exception e){
17 e.printStackTrace();
18 }
19 }
20 Logger logger = Logger.getLogger(DemoHandler.class);
21 public void handler(InputStream input, OutputStream output, CfcContext context) throws Exception {
22 logger.info("info log");
23 logger.warning("warn log");
24 output.write("hello world!".getBytes());
25 }
26}
使用log4j输出日志
增加依赖:
在pom.xml文件中,>
标签下加入这一段:
1<dependency>
2 <groupId>log4j</groupId>
3 <artifactId>log4j</artifactId>
4 <version>1.2.17</version>
5</dependency>
配置log4j
创建配置文件src/main/resources/log4j.properties
1log4j.rootLogger = debug,stdout
2
3### 输出信息到控制台 ###
4log4j.appender.stdout = org.apache.log4j.ConsoleAppender
5log4j.appender.stdout.Target = System.out
6log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
7log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
代码中使用log4j
1package com.baidu.demo.log4j;
2
3import com.baidubce.cfc.core.StreamHandler;
4import org.apache.log4j.Logger;
5import com.baidubce.cfc.core.CfcContext;
6import com.baidubce.cfc.core.StsCredential;
7import com.fasterxml.jackson.databind.ObjectMapper;
8
9import java.io.InputStream;
10import java.io.OutputStream;
11import java.io.PrintStream;
12
13public class DemoHandler implements StreamHandler {
14 Logger logger = Logger.getLogger(DemoHandler.class);
15
16 public DemoHandler() {
17 }
18
19 public void handler(InputStream input, OutputStream output, CfcContext context) throws Exception {
20 ObjectMapper mapper = new ObjectMapper();
21 InvokeEvent event = mapper.readValue(input, InvokeEvent.class);
22 if (event.getEvent() != null) {
23 logger.info(event.getEvent());
24 }
25
26 PrintStream stream = new PrintStream(output);
27 stream.println("Hello world");
28 stream.close();
29 }
30}
代码示例
- 本章节中举例的Event模式的简单示例,请点击下载 简单示例
- 本章节中举例的Stream模式示例,请点击下载使用Stream模式
- 本章节中举例的log4j输出日志示例,请点击下载 使用log4j输出日志