全部文档
当前文档

暂无内容

如果没有找到您期望的内容,请尝试其他搜索词

文档中心

Basic Http Server应用示例

最近更新时间:2023-02-03 17:38:12

创建一个Basic Http Java项目,示例如下:

1. 添加pom依赖

在pom.xml文件需要添加下列依赖内容:

<properties>
    <project.version>2.3.0</project.version>
  </properties>

 <dependencies>
        <dependency>
            <groupId>io.cloudevents</groupId>
            <artifactId>cloudevents-http-basic</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>io.cloudevents</groupId>
            <artifactId>cloudevents-json-jackson</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>9.4.41.v20210516</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.0-alpha6</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>2.0.0-alpha6</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
    </dependencies>

2. 新建一个main函数

创建Server,加载handlers,启动服务start,最后加入服务器join。

package io.cloudevents.examples.http.basic.server;

import io.cloudevents.examples.http.basic.handler.CustomHandler;
import io.cloudevents.examples.http.basic.handler.HealthCheckHandler;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;

import java.io.InputStream;
import java.net.InetSocketAddress;
import java.util.Properties;

@Slf4j
public class JettyServer {
    public static void main(String[] args) throws Exception {
        String serverPort = loadHttpServerPort();
        if (serverPort == null || serverPort.equals("")) {
            log.error("Usage: HTTPServer <port>");
            return;
        }
        Server server = new Server(new InetSocketAddress("localhost", Integer.parseInt(serverPort)));
        HandlerList handlerList = new HandlerList();
        handlerList.addHandler(new HealthCheckHandler());
        handlerList.addHandler(new CustomHandler());
        server.setHandler(handlerList);
        server.start();
        server.join();
    }

    public static String loadHttpServerPort() {
        Properties properties = new Properties();
        try {
            InputStream inputStream = ClassLoader.getSystemResourceAsStream("application.properties");
            properties.load(inputStream);
            String port = properties.getProperty("server.port");
            log.info("Http Server Port: {}", port);
            return port;
        } catch (Exception e) {
            log.error("Load Properties From Config error", e);
            return null;
        }
    }
}

3. Http Server监听端口资源配置

Http Server启动端口可以通过resources/application.properties文件进行配置。

server.port=8080

4. 添加Handler实现

用于处理接收请求的业务逻辑,您可以自定义handler进行业务处理,下面列举出2个handler示例
HealthCheckHandler用于检测函数是否正常启动

package io.cloudevents.examples.http.basic.handler;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

@Slf4j
public class HealthCheckHandler extends AbstractHandler {

    @Override
    public void handle(String uri,
                       Request request,
                       HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse) throws IOException, ServletException {
        if ("/health".equalsIgnoreCase(uri)) {
            log.info("health check");
            httpServletResponse.setContentType("application/json;charset=UTF-8");
            OutputStream outputStream = httpServletResponse.getOutputStream();
            String data = "Hands Up";
            byte[] dataByteArr = data.getBytes(StandardCharsets.UTF_8);
            outputStream.write(dataByteArr);
            httpServletResponse.setContentLength(data.length());
            httpServletResponse.setStatus(HttpStatus.OK_200);
            ((Request) request).setHandled(true);
        }
    }
}

CustomHandler用于处理事件函数请求

package io.cloudevents.examples.http.basic.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.cloudevents.CloudEvent;
import io.cloudevents.core.message.MessageReader;
import io.cloudevents.core.message.MessageWriter;
import io.cloudevents.examples.http.basic.Foo;
import io.cloudevents.examples.http.basic.IOUtils;
import io.cloudevents.http.HttpMessageFactory;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Enumeration;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

@Slf4j

public class CustomHandler extends AbstractHandler {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void handle(String uri,
                       Request request,
                       HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse) throws IOException, ServletException {
        if (!"/event-invoke".equalsIgnoreCase(uri)) {
            httpServletResponse.setStatus(HttpStatus.NOT_FOUND_404);
            return;
        }
        if (!"POST".equalsIgnoreCase(request.getMethod())) {
            httpServletResponse.setStatus(HttpStatus.METHOD_NOT_ALLOWED_405);
            return;
        }

        CloudEvent receivedEvent = createMessageReader(httpServletRequest).toEvent();
        log.info("begin receive event: {}", receivedEvent);
        log.info("receive event string data: {}", new String(receivedEvent.getData().toBytes()));
        Ks3CloudEventData ks3Data = objectMapper.readValue(receivedEvent.getData().toBytes(), Ks3CloudEventData.class);
        log.info("ks3Data : {}", ks3Data );


        createMessageWriter(httpServletResponse).writeBinary(receivedEvent);
        ((Request) request).setHandled(true);
    }

    private static MessageReader createMessageReader(HttpServletRequest httpServletRequest) throws IOException {
        Consumer<BiConsumer<String, String>> forEachHeader = processHeader -> {
            Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                processHeader.accept(name, httpServletRequest.getHeader(name));

            }
        };
        byte[] body = IOUtils.toByteArray(httpServletRequest.getInputStream());
        return HttpMessageFactory.createReader(forEachHeader, body);
    }

其中createMessageReader方法将httpServletRequest请求数据转换成cloudevents对象格式,请求对象和和请求头均可以通过cloudevents对象进行获取。
createMessageWriter将cloudevents对象转换成HttpServletResponse协议对象来返回响应头和响应体。

5. 编译打包

在pom.xml文件中添加maven-assembly-plugin插件(打包插件您可以自行选择,此处将maven-assembly-plugin插件作为示例)。

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>
io.cloudevents.examples.http.basic.server.JettyServer
                                </mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <appendAssemblyId>false</appendAssemblyId>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

使用下面命令将代码和及其依赖打包成可执行的jar包,编译后的jar包位于项目文件内的target目录内。

maven package

编译好的jar包需用zip工具进行压缩,用于后续控制台的代码包上传。

6. 代码包上传云函数

  • 登录云函数控制台
  • 在顶部菜单栏,选择地域命名空间
  • 在函数管理页面,选择新建函数
  • 在环境配置中,代码上传方式选择通过zip包上传,或通过对象存储(ks3)上传
  • 完善其他函数配置,点击创建按钮完成函数创建。

7. Gradle编译打包

gradle使用build.gradle配置文件进行编译。build.gradle配置文件如下:

plugins {
    id 'java'
    id 'com.github.johnrengelman.shadow' version '7.1.2'
}

group 'org.example'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}


repositories {
   mavenCentral()
}

dependencies {
    implementation 'io.cloudevents:cloudevents-http-basic:2.3.0'
    implementation 'io.cloudevents:cloudevents-json-jackson:2.3.0'
    implementation 'org.eclipse.jetty:jetty-server:9.4.41.v20210516'
    implementation 'org.slf4j:slf4j-api:2.0.0-alpha6'
    implementation 'org.slf4j:slf4j-simple:2.0.0-alpha6'
    implementation "org.projectlombok:lombok:1.18.22"
    annotationProcessor "org.projectlombok:lombok:1.18.22"
}

description = 'cloudevents-basic-http-example'

shadowJar {
    manifest {
        attributes 'Main-Class': 'io.cloudevents.examples.http.basic.JettyServer'
    }
}

test {
    useJUnitPlatform()
}

其中com.github.johnrengelman.shadow插件将程序打包fat jar,包含程序运行所有依赖的Jar包,可以直接使用java -jar 【name】运行。其中attributes 下Main-Class属性需要和代码中Main函数名称保持一致。
在项目的根目录下执行gradle shadow命令打包,编译输出如下:

gradle shadow

编译输出示例

BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

编译后的jar包位于项目文件内的build/libs目录下。
如果显示编译失败,请根据输出的编译错误信息调整代码。

文档导读
纯净模式常规模式

纯净模式

点击可全屏预览文档内容
文档反馈