Vert.x(vertx) 创建HTTP服务

Vert.x底层通信框架依赖于Netty,并封装了对Http协议的支持,因此可以非常方便的进行Web开发,且不依赖于任何中间件。笔者所在的公司老系统使用的是SSM架构的项目,部署在Weblogic上,每年花在中间件上的钱就非常多,现在全面改造为Vert.x,中间件的费用直接就省了。另外不依赖中间件,编程会变得非常灵活,定制性非常强,安全性也会得到一定层度的提高。

对于实现一个简单的web服务,有很多种选择,简单划为三种

  1. 这是使用最多的一种,也是很多的Java开发者可能最先想到的,就是使用Java中间件来实现,只要下载一个Tomcat,再编写个web项目就可以对外提供Web服务。这种方式我们完全不需要考虑线程的交互,不需要考虑网络协议,只需要关注业务逻辑,可以说是一种全包的形式。
  2. 使用Java原生的Socket或者NIO来实现,但这种方式比较复杂,对编程功底要求最高,而且自己实现很难保证性能和稳定性。这种方式完全需要手动处理,很少会使用这种方式来实现HTTPServer,可以说这是最为原始形式。
  3. 介于全包和原始形式之间,就是用第三方的框架来实现,比如Vertx或者偏底层的Netty。你可以利用框架封装的API简单的创建一个HttpServer,并不需要关注底层的通信协议。这种方式更为灵活,一般来讲性能也更高,并且不依赖中间件。

下面简单的来实现一个HttpServer,通过浏览器访问这个HttpServer能够在浏览器上显示HelloWorld。下面简单列出实现的步骤:

  1.  创建一个Maven项目,并配置依赖的包。(这里仅仅需要引入vertx-core的包即可)
  2. 创建一个核心类,创建main方法,直接在main方法中编写代码即可(后期会进行改造)
  3. 直接运行核心类,并通过浏览器访问

下面是具体的代码

1.pom文件

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-core</artifactId>
    <version>3.5.2</version>
</dependency>

2. 创建核心类MyHttpServer

package com.stu.vertx.hello;

import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerResponse;

/**
 * Vertx 创建一个最简单的HttpServer,当用户请求时返回Hello World
 * 
 * @author lenovo
 *
 */
public class MyHttpServer {
	
	public static void main(String[] args) {
		
		Vertx vertx = Vertx.vertx();
		
		// 创建一个HttpServer
		HttpServer server = vertx.createHttpServer();
		
		server.requestHandler(request -> {
			// 获取到response对象
			HttpServerResponse response = request.response();
			
			// 设置响应头
			response.putHeader("Content-type", "text/html;charset=utf-8");
			
			// 响应数据
			response.end("Hello World");
			
		});
		
		server.listen(8888); // 监听8888端口
	}

}

代码非常简单,首先获取到Vertx对象,然后通过vertx对象创建Http服务,监听Http请求并进行处理。

这里用到了JDK8的新特性,第一个是Vertx.vertx()方法,我们知道Vertx是一个接口,按照我们以前的逻辑,方法实现是不能写在接口中的,在JDK8中增加了静态方法和默认方法。第二个是->这个符合,这也是一个新特性,可能看起来比较难懂,可以类比JavaScript来理解,JavaScript中有很多这样的写法。我们可以看到,这个方法实际上是接收一个Handle接口,Handle接口中有一个抽象方法 public void handle(HttpServerRequest request) ,这个方法有一个参数 HttpServerRequest .按照我们之前的写法应该写成如下代码:

server.requestHandler(new Handler<HttpServerRequest>() {
			
    @Override
    public void handle(HttpServerRequest request) {
				
        // 获取到response对象
        HttpServerResponse response = request.response();
				
        // 设置响应头
        response.putHeader("Content-type", "text/html;charset=utf-8");
				
        // 响应数据
        response.end("Hello World");
    }
});

对比两者可以发现,实际上就是简化了new 子类,简化了重写方法,直接把方法的参数后跟->{方法体}来解决。这样写起来是非常方便的。但是这种写法一个接口中只能定义一个抽象方法。这种接口一般会打上@FunctionalInterface注解。

上面那段代码是直接写到main方法中的,可以直接运行即可。监听的是8888端口,在启动的过程中,要保证8888端口不被占用。启动成功之后可以直接通过浏览器访问。

3.浏览器访问 localhost:8888

到这里,一个简单的Vertx程序就写完了。

代码改进

在上面演示的创建HttpServer的方式我们会发现有一个很大的问题,就是所有的代码都写在main方法中,这样显然是不好的。Vert.x推荐的写法是为每一个应用创建一个Verticle,也就是Vert.x的模块,然后通过Vertx核心接口,部署Verticle模块。多个Verticle模块之间可以通过EventBus进行相互调用。

这里提到了Verticle、EventBus等,这些都是Vert.x中一些非常重要的概念。Verticle可以简单的理解为继承了AbstractVerticle的类都是一个Verticle,每个Verticle可以单独部署或者单独运行。EventBus看不见,摸不着,可以简单的理解为,各Verticle模块之间通信的桥梁。

下面我们就创建一个HttpServer的Verticle模块,并部署到Vertx中运行,实现步骤如下:

  1. 创建一个类,继承AbstractVerticle类
  2. 重写start方法和stop方法,在start方法中处理业务逻辑,stop方法中释放资源
  3. 在main方法中部署Verticle模块
  4. 启动服务,并通过浏览器进行访问

这里我们只需要粘贴Verticle核心代码:

public class MyHttpServer2 extends AbstractVerticle {

	public static void main(String[] args) {
		MyHttpServer2 verticle = new MyHttpServer2();
		Vertx vertx = Vertx.vertx();

		// 部署verticle,这里会调用start方法
		vertx.deployVerticle(verticle);
	}

	@Override
	public void start() {
		// 在这里可以通过this.vertx获取到当前的Vertx
		Vertx vertx = this.vertx;

		// 下面可以实现helloworld中相同的功能

		// 创建一个HttpServer
		HttpServer server = vertx.createHttpServer();

		server.requestHandler(request -> {
			// 获取到response对象
			HttpServerResponse response = request.response();

			// 设置响应头
			response.putHeader("Content-type", "text/html;charset=utf-8");

			// 响应数据
			response.end("Hello World");

		});

		server.listen(8889);

	}

	@Override
	public void stop() throws Exception {
		super.stop();
	}

}

上面代码比较简单,start方法的实现和第一个演示中的main方法代码非常相似,start方法中之所以可以直接使用vertx这个变量,是因为继承了AbstractVerticle这个类,在这个类里有一个protected类型的Vertx变量。

另外在main方法中,获取Vertx实例是通过Vertx.vertx()方法,查看代码会发现,Vertx是一个接口,按照之前的逻辑,接口中只能定义抽象方法,这是什么情况呢?这也是JDK8的新特性,接口中可以定义静态方法。也就是说我们调用的是接口中的静态方法,也就是已经实现了的方法。在Vertx中,这种方式非常常见。

这种编码方式是Vertx官方所支持的方式,后面的案例都会通过这种方式来进行编写。

到这里,我们了解了创建HttpServer的API,我们发现,Vertx的API还是非常简洁,好用的。但本节的重点还是Verticle模块的理解和编写。

当然了,如果要真正的实现一个HttpServer,还需要更多的东西,比如路由,Session,Rest接口开发,模板,WebSocket等等,后续我们会陆续整理后发布!

相关文章

(一)Vert.x 简明介绍 Vert.x(vertx) 简明介绍_jhappyfly的博客-CSDN博客

(二)Vert.x创建简单的HTTP服务 Vert.x(vertx) 创建HTTP服务_jhappyfly的博客-CSDN博客

(三)Vert.x Web开发之路由 Vert.x(vertx) Web开发-路由_vert.x web开发_jhappyfly的博客-CSDN博客

(四)Vert.x TCP服务实现 Vert.x(vertx) 实现TCP服务_vertx怎么在任意地方写数据到tcp连接_jhappyfly的博客-CSDN博客

(五)Vert.x数据库访问 Vert.x(vertx) 连接MySQL、Oracle数据库_vertx mybatis_jhappyfly的博客-CSDN博客

(六)Vert.x认证和授权 Vert.x(vertx) 认证和授权详解(包含认证和授权在Web系统中的使用)_vertx auth_jhappyfly的博客-CSDN博客

(七)Vert.x事件总线(Event Bus)与远程服务调用 Vert.x(vertx) 事件总线(EventBus)与 远程服务调用_vertx.eventbus_jhappyfly的博客-CSDN博客

Vert.x 案例代码:https://github.com/happy-fly
 

Vert.x 是一个基于事件驱动、非阻塞的应用框架,它提供了一种简单且高性能的方式来构建分布式、并发的应用程序。Vert.x 还提供了一系列的扩展,以支持多种协议和通信方式。 Vert.x 提供了一个名为 Vert.x MQTT 的模块,用于构建 MQTT 服务器。MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传输协议,常用于物联网设备之间的通信。 使用 Vert.x MQTT 服务器,你可以轻松地构建基于 MQTT 协议的应用。你可以使用 Vert.x 提供的异步、非阻塞的特性来处理大量的并发连接,并且可以利用 Vert.x 的事件总线机制来实现消息的发布和订阅。 要使用 Vert.x MQTT 服务器,你需要导入相应的依赖,并编写相应的代码来配置和启动服务器。以下是一个简单的示例代码: ```java import io.vertx.core.Vertx; import io.vertx.mqtt.MqttServer; public class MqttServerExample { public static void main(String[] args) { Vertx vertx = Vertx.vertx(); MqttServer mqttServer = MqttServer.create(vertx); mqttServer.endpointHandler(endpoint -> { System.out.println("Client connected: " + endpoint.clientIdentifier()); endpoint.accept(false); // 拒绝连接 endpoint.disconnectHandler(h -> { System.out.println("Client disconnected: " + endpoint.clientIdentifier()); }); endpoint.subscribeHandler(subscribe -> { System.out.println("Client subscribed: " + endpoint.clientIdentifier()); subscribe.complete(true); // 接受订阅请求 }); endpoint.unsubscribeHandler(unsubscribe -> { System.out.println("Client unsubscribed: " + endpoint.clientIdentifier()); unsubscribe.complete(true); // 接受取消订阅请求 }); endpoint.publishHandler(publish -> { System.out.println("Received message from client: " + publish.payload().toString()); }); }); mqttServer.listen(1883, "0.0.0.0", ar -> { if (ar.succeeded()) { System.out.println("MQTT server started"); } else { System.out.println("MQTT server failed to start"); } }); } } ``` 以上示例代码创建了一个简单的 MQTT 服务器,监听在本地的 1883 端口。当有客户端连接、订阅、取消订阅或发布消息时,会打印相应的日志。你可以根据自己的需求来扩展代码,实现更复杂的功能。 希望以上信息对你有帮助!如果你有任何问题,可以继续提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值