java - 如何从我的 servlet 中获取 org.eclipse.jetty.server.Request
问题描述
考虑这段代码。这是一项正在进行中的工作,但目标是获得一个 NIO 通道,我可以使用它来创建一个全双工 RubyIO 实例 (org.jruby.RubyIO),它可以由 NIO 选择器选择。
但首先我想要一个 NIO 通道......
// This call returns a `javax.servlet.ServletRequest` but the underlying
// instance was created by Jetty - it seems to me - and is actually an
// `org.eclipse.jetty.server.Request`
ServletRequest srv_req = this.http_servlet_request_wrapper.getRequest();
Request req;
ClassLoader cl1 = Request.class.getClassLoader();
ClassLoader cl2 = srv_req.getClass().getClassLoader();
System.out.println("DBG: cl1: " + cl1.toString());
// => DBG: cl1: WebAppClassLoader{66233253}@3f2a3a5
System.out.println("DBG: cl2: " + cl2.toString());
// => DBG: cl2: java.net.URLClassLoader@63947c6b
if (srv_req instanceof Request) {
System.out.println("DBG: srv_req IS REQUEST");
req = (Request)srv_req;
System.out.println("DBG: req class: " + req.getClass().getName());
} else {
System.out.println("DBG: srv_req IS NOT REQUEST");
System.out.println("DBG: srv_req class: " + srv_req.getClass().getName());
throw new Exception("<expletive deleted>!");
}
HttpChannel http_channel = req.getHttpChannel();
EndPoint end_point = http_channel.getEndPoint();
控制台输出什么...
DBG: cl1: WebAppClassLoader{66233253}@3f2a3a5
DBG: cl2: java.net.URLClassLoader@63947c6b
DBG: srv_req IS NOT REQUEST
DBG: srv_req class: org.eclipse.jetty.server.Request
最后抛出异常。
所以似乎这instanceof
不是srv_req
一个实例,
Reuest
因为类加载器不一样。不过, 的类srv_req
是org.eclipse.jetty.server.Request
。但是在 servlet 中,我不能这样对待它,也不能强制转换它。
我已阅读https://www.eclipse.org/jetty/documentation/current/jetty-classloading.html
但我仍然不清楚如何srv_req
作为
org.eclipse.jetty.server.Request
实例访问。
我怀疑我不应该能够从 servlet 执行此操作,但问一下也无妨。
我可以访问javax.servlet.ServletRequest
从我的
HttpServletRequestWrapper
对象返回的 , 它看起来是一个
org.eclispe.jetty.server.Request
实例吗?
或者,我可以从我可以在 servlet 中访问的内容创建一个全双工 NIO 通道吗?
解决方案
首先,org.eclipse.jetty.server.Request
要从javax.servlet.HttpServletRequest
使用...
Request baseRequest = Request.getBaseRequest(httpServletRequest);
但这不会让你走得很远。
org.eclipse.jetty.server.HttpChannel
并且org.eclipse.jetty.io.EndPoint
不会将 NIO 接口或行为暴露给应用程序。
它们是通过单个接口实现 HTTP 规范行为的内部类,用于处理...
- 传输编码
- 分块
- 内容编码
- 压缩包
- 多部分编码
- ETC ..
这正是 HTTP/1.1 带来的结果,如果您开始使用 HTTP/2,事情会变得更加复杂(通过物理连接控制许多虚拟流)。
但是,如果您不想使用或不关心 HTTP 怎么办?
Connection
您可以使用自己的对象升级连接并从 HTTP 下退出。
jettyEndPoint.setConnection(myConnection);
jettyEndPoint.upgrade(myConnection);
不要忘记实现Connection.UpgradeTo
从先前连接中获取延迟(未处理)字节。
但这仍然不能让您获得 NIO,因为EndPoint
Jetty 并没有放弃它,它仍然在进行选择器管理和低级协议行为。(例如来自 HTTP/2 的流)
好的,回到 HTTP,你还有什么选择?
没有任何东西可以暴露或让您管理 NIO 选择器。
您将不得不伪造 jruby 的选择器。
如果您想坚持使用 HTTP,则使用 servlet 规范 Async I/O 行为作为您的 Jetty 端 API 层。
如果您不想坚持使用 HTTP,则将连接从 HTTP 升级,只需确保您在 HTTP 对话中首先使用适当的标头(例如:)这样说Connection: upgrade
。
推荐阅读
- python-2.7 - 无法安装 python cityhash
- javascript - 与在 google-docs 中使用 google-apps-scripts 的 doc 模板占位符的 appendText 方法相比,setText 方法没有正确循环
- r - 如何在没有名称的表格中“交叉”单元格
- sql - 按重复的列分组
- codenameone - 在命令行或直接在代号一个资源文件中插入数据
- c# - 拥有静态 IReadOnlyDictionary 字段是否是线程安全的?
- jdbc - Kafka Source Connect 似乎没有做任何事情
- mysql - 在运行 nginx 入口控制器 kubernetes 时需要(内部)服务名称
- node.js - 除了全局变量之外,是否还有其他需要通用节点模块的替代方法?
- objective-c - 在 dispatch_async 队列中的 weakself(dispatch_get_main_queue(), ^{})