Java 18中简单 Web 服务器

从 Java 18 开始,我们可以访问JEP 408中引入的简单 Web 服务器。我们可以通过命令行工具和 API 访问其功能。

简单 Web 服务器提供了一个提供静态文件服务的基本 Web 服务器。它被描述为对于测试、原型设计和教育很有用。该服务器有意使其设置和运行非常简单,并不旨在与Apache Tomcat或Jetty等功能更齐全的选项竞争或取代。

引入该工具的目标之一是让开发人员以尽可能少的障碍启动并运行 Web 开发。

jwebserver命令行工具
启动服务器的第一个也是最简单的方法是使用提供的命令行工具。

单独使用命令jwebserver就足以启动服务器。

如果一切正常,我们会看到以下响应:

$ jwebserver         
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /usr and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/

默认情况下,运行命令时所在的目录就是所提供的目录,即上例中的/usr 。但是,我们可以使用-d标志更改目录:

$ jwebserver -d /opt
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /opt and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/

值得注意的是,我们必须在这里提供绝对路径。

我们还可以使用-p和 -b标志更改端口和地址 :

$ jwebserver -b 0.0.0.0 -p 3003    
Serving / and subdirectories on 0.0.0.0 (all interfaces) port 3003
URL http://192.168.1.1:3003/

运行上述配置会将我们的当前目录公开给网络上输出中给出的 IP 地址的任何人。虽然如果我们尝试传输文件,这可能很有用,但我们应该确保我们乐意首先共享它们。

API
使用简单 Web 服务器的第二个选项是 API。通过使用它,我们可以获得更多的控制权并自定义请求的处理方式。

首先,让我们使用 API 重新创建命令行 Web 服务器。

为此,我们将使用SimpleFileServer 类。 我们可以使用这个类来做三件事——创建HttpServer、创建HttpHandler和创建HttpFilter。

首先,我们将使用createFileServer()创建并启动服务器:

public static void main(String[] args) {
InetSocketAddress address = new InetSocketAddress(8080);
Path path = Path.of("/");
HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE);
server.start();
}

这里我们使用 InetSocketAddress类指定了一个地址。我们还可以更改此处地址的其余部分,而不仅仅是端口。

然后,我们设置了一个 指向我们想要服务的目录的Path对象。

接下来,我们将这些作为参数以及日志记录级别传递给createFileServer()。和以前一样,我们可以配置其中任何一个来满足我们的需求。生成的 Web 服务器与使用命令行工具创建的 Web 服务器相同,可以通过我们的浏览器访问127.0.0.1:8080。

处理程序
显然,创建上面的服务器并没有比命令行工具提供任何好处。为了开始获得一些控制权,我们需要引入一个HttpHandler。

让我们看看向我们的服务器添加一个自定义的。我们可以使用SimpleFileServer的 另一种方法createFileHandler()创建一个处理程序。假设我们已经有一个像之前创建的服务器一样的服务器,我们可以将新的处理程序附加到它:

HttpHandler handler = SimpleFileServer.createFileHandler(Path.of("/Users"));
server.createContext("/test", handler);

这会导致所有流向127.0.0.1:8080/test 的流量都通过我们的新处理程序。

我们可以使用处理程序做更多的事情。例如,让我们设置一个服务器来模拟在不同端点上允许和拒绝访问。我们可以使用HttpHandlers.of()方法来创建允许和拒绝访问的响应:

HttpHandler allowedResponse = HttpHandlers.of(200, Headers.of("Allow", "GET"), "Welcome");
HttpHandler deniedResponse = HttpHandlers.of(401, Headers.of("Deny", "GET"), "Denied");

接下来,我们需要定义一个谓词来决定何时返回每个响应:

Predicate findAllowedPath = r -> r.getRequestURI()
.getPath().equals("/test/allowed");

仅当我们尝试访问 URL /test/allowed时,才会返回true。所有其他端点均失败。

我们现在可以使用 HttpHandlers.handleOrElse(),它接受我们的 谓词和两个选项。如果谓词通过,则执行第一个,否则执行第二个:

HttpHandler handler = HttpHandlers.handleOrElse(findAllowedPath, allowedResponse, deniedResponse);

最后,我们可以像以前一样使用新的 HttpHandler设置HttpServer:

HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE);
server.createContext("/test", handler);

结果是,导航到http://127.0.0.1:8080/test/allowed显示文本“ Welcome ”以及200响应。导航到任何其他路径都会显示“拒绝”并显示401响应。我们可以根据需要使用它来设置测试环境。然而,潜在的复杂性相当低。

过滤器
SimpleFileServer类的最后一个方面 是创建 Filter 的能力。该过滤器的作用是处理日志消息。通过定义我们自己的,我们可以将消息重定向到我们选择的OutputStream 。

应用Filter时,服务器的创建有所不同 。首先,让我们使用createOutputFilter()创建过滤器:

Filter filter = SimpleFileServer.createOutputFilter(System.out, SimpleFileServer.OutputLevel.INFO);

我们在这里使用 System.out作为OutputStream的简单示例 ,但我们也可以使用记录器或任何我们想要的东西。

接下来,我们将 HttpServer类中的create()方法 与我们刚刚创建的过滤器一起使用:

HttpServer server = HttpServer.create(new InetSocketAddress(8080), 10, "/test", handler, filter);

这里有一些争论,所以让我们来看看它们。首先,地址与以前一样采用InetSocketAddress的形式。其次,一个整数指定套接字积压。这是一次允许排队的最大 TCP 连接数。第三,我们有背景。在这里,我们指定要处理到达127.0.0.1:8080/test 的流量。第四个参数是HttpHandler,与我们之前创建的类似。最后是我们的过滤器作为第五个参数。

这提供了与我们之前使用处理程序时相同的功能。然而,我们现在可以完全控制日志输出。

结论
在本文中,我们看到我们可以快速启动 Java 18 的简单 Web 服务器,并且它提供了少量有用的功能。

首先,我们看到通过使用命令行工具jwebserver我们可以立即启动并运行服务器。该服务器提供对我们运行它的位置中的文件和子目录的读取访问权限。

接下来,我们查看了 API 和可用的新类,例如SimpleFileServer。使用此 API,我们可以实现与命令行工具相同的结果,但以编程方式实现。我们还可以使用HttpHandler 和Filter来扩展我们的控制。

https://www.jdon.com/72671.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/707914.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Azure DevOps和Jira比较

最近需要对管理工具调研,客户现在使用范围较广的就是Azure DevOps,使用的是一个免费版本,需要对工具自身的特长和客户的使用情况,进行一个调研。 查了一下资料,还有客户现在的使用情况,做一个总结。 两者…

IntelliJ IDEA 常用快捷键和下载链接

下载链接(windows) 下载 IntelliJ IDEA – 领先的 Java 和 Kotlin IDE 编码时: 跳转到引用方法的地方 (有多个引用时会出现下拉列表) ctrl鼠标左键 跳转后回到原来的地方 …

vscode windows 免密登录 powershell.sh

Linux 生成秘钥 ssh-keygenwindows powershell.sh $HOST_IP"zhang192.168.1.1" $PUBPATH"$HOME\.ssh\id_rsa.pub" $KEY(Get-Content "$PUBPATH" | Out-String); ssh "$HOST_IP" "mkdir -p ~/.ssh && chmod 700 ~/.ssh …

微信小程序 --- mobx-miniprogram miniprogram-computed

1.1 mobx-miniprogram 介绍 目前已经学习了 6 种小程序页面、组件间的数据通信方案,分别是: 数据绑定:properties获取组件实例:this.selectComponent()事件绑定:this.triggerEvent()获取应用实例:getApp(…

LeetCode 2120.执行所有后缀指令

现有一个 n x n 大小的网格,左上角单元格坐标 (0, 0) ,右下角单元格坐标 (n - 1, n - 1) 。给你整数 n 和一个整数数组 startPos ,其中 startPos [startrow, startcol] 表示机器人最开始在坐标为 (startrow, startcol) 的单元格上。 另给你…

动态给vue的data添加新属性页面不更新的原因分析以及解决方法

直接添加属性的问题 我们从一个例子触发 定义一个p标签&#xff0c;通过v-for指令进行遍历&#xff0c;然后通过绑定事件&#xff0c;触发事件的时候&#xff0c;将动态添加哟个属性。 预期结果&#xff1a;动态增加的属性也被遍历显示在页面上 <p v-for"(value,ke…

Android 15 第一个开发者预览版-Android15的新变化

版本说明 发布日期2024 年 2 月 16 日buildAP31.240119.016模拟器支持x86&#xff08;64 位&#xff09;、ARM (v8-A)安全补丁级别2024 年 2 月Google Play 服务2015 年 2 月 24 日API diffAPI 34 → V DP1 Android 15 将继续致力于构建一个平台&#xff0c;在帮助提高效率的…

后端程序员入门react笔记(六)- 讲透Promise与Fetch

js声明变量的三种方式 我们通常使用 var let 和const来声明js的变量&#xff0c;但是这三者有什么区别呢&#xff1f; var的变量可以是全局的或者函数作用域&#xff0c;而let和const只能是块级作用域var和let可以重新赋值&#xff0c;而const是不允许重新赋值的&#xff0c;…

【王道数据结构】【chapter7查找】【P285t5】

线性表中各节点的检索概率不等时&#xff0c;可用如下策略提高顺序检索的效率&#xff1b;若找到指定的结点&#xff0c;则将该结点和其前驱结点&#xff08;若存在&#xff09;交换&#xff0c;使得经常被访问的结点尽量位于表的前端。试设计在顺序结构和链式结构的线性表盘上…

python中集合(Set)和列表(List)性能比较

文章目录 引言1. Set和List2. 性能对比3. 总结 引言 在当今的软件开发过程中&#xff0c;Python 已经成为了一种极为流行的编程语言&#xff0c;得益于其简洁的语法和强大的库支持。在 Python 中&#xff0c;列表&#xff08;List&#xff09;和集合&#xff08;Set&#xff0…

敏捷开发中如何写好用户故事?

什么是用户故事&#xff1f; 用户故事&#xff08;user story&#xff09;是一个用来确认用户和用户需求的简短描述&#xff0c;作为什么用户&#xff0c;希望如何&#xff0c;这样做的目的或者价值何在。用户故事在软件研发中又被描述为需求。用户故事通常的格式为&#xff1…

【一】【计算机网络】win基本命令

检查自己的信息 以太网IPv4 地址就是本地计算机。 以太网适配器 VMware Network Adapter VMnet1的IPv4 地址不是本地计算机。局域网内其他的计算机。 C:\Users\205>ipconfigWindows IP 配置以太网适配器 以太网:连接特定的 DNS 后缀 . . . . . . . :本地链接 IPv6 地址. .…

【Android】切换系统全局语言设置

前两种为应用内部处理&#xff0c;第三种为发送广播由系统服务进行处理 使用反射 这种会直接将安卓设置内的语言列表清空&#xff0c;然后将选择的语言设置为系统语言 该方法存在问题&#xff0c;在首次开机后设置会导致国外应用进不去(只对于here地图个别版本) /*** 设置语言…

STL容器之list

​ 1.封装除了对数据的保护、更好地管理数据之外&#xff0c;还有实现了对上层的统一&#xff1b; ​ 2.类模板参数的不同&#xff0c;一方面是为了实例化出来不同的类&#xff0c;另一方面是为了实现类的成员函数的不同&#xff1b; 一、认识list ​ 1.list是一种带头双向循…

隐藏 IP 地址调用外部接口:探索与实践

目录 探索隐藏自己的 IP 调用别人的接口1. 使用代理服务器代码示例实际场景 2. 使用 VPN实际场景 3. 使用 Tor 匿名网络实际场景 结语 引言&#xff1a; 在网络开发中&#xff0c;有时我们需要调用外部接口来获取数据或执行某些操作。然而&#xff0c;有些情况下&#xff0c;我…

java高并发场景面试题,干货来袭

为什么阿里巴巴的持久层抛弃hibernate&#xff0c;采用MyBatis框架&#xff1f; 原因大概有以下4点&#xff1a; 尤其是需要处理大量数据或者大并发情况的网站服务&#xff0c;这也阿里选择MyBatis的原因。 MyBatis整体架构 不多讲&#xff0c;先看目录图 MyBatis源码笔记文档…

捕获在野SMBGhost本地提权攻击样本

前言 从Windows10 v1903/Windows Server v1903开始&#xff0c;微软在协议SMB3.1.1中开启了对数据压缩传输的支持&#xff0c;但是由于SMB没有正确处理压缩的数据包&#xff0c;在客户端/服务端解压数据的时候&#xff0c;没有对COMPRESSIN_TRANSFORM_HEADE结构进行安全校验&a…

【mysql 数据库事务】开启事务操作数据库,写入失败后,不回滚,会有问题么? 这里隐藏着大坑,复试,面试时可以镇住面试老师!!!!

建表字段: CREATE TABLE user (id INT(11) NOT NULL AUTO_INCREMENT,nickname VARCHAR(32) NOT NULL COLLATE utf8mb4_general_ci,email VARCHAR(32) NOT NULL COLLATE utf8mb4_general_ci,status SMALLINT(6) UNSIGNED NULL DEFAULT NULL,password VARCHAR(256) NULL DEFAULT…

QT两个类之间使用信号槽

在做一些东西的时候&#xff0c;习惯性的引入头文件并且调用&#xff0c;因此出现了很多bug,qt的信号槽机制便可以有效的避免一些问题。 A类 #ifndef A_H #define A_H#include <QObject> #include <QDebug> class A : public QObject {Q_OBJECT public:explicit A…

Netty入门指南:从零开始的异步网络通信

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Netty入门指南&#xff1a;从零开始的异步网络通信 前言Netty简介由来&#xff1a;发展历程&#xff1a;异步、事件驱动的编程模型&#xff1a; 核心组件解析通信协议高性能特性异步编程范式性能优化与…