[英]java.lang.ClassNotFoundException: org.eclipse.jetty.server.Request when starting with jetty:run-forked and connecting with ssl
[英]How do I get the org.eclipse.jetty.server.Request from within my servlet
考慮一下這段代碼。 這是一項正在進行的工作,但目標是讓我掌握一個 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 中做到這一點,但是提出這個問題並沒有什么壞處。
我可以訪問從我的HttpServletRequestWrapper
對象返回的javax.servlet.ServletRequest
,它看起來是一個org.eclispe.jetty.server.Request
實例嗎?
或者,我可以從我可以在 servlet 中訪問的內容創建一個全雙工 NIO 通道嗎?
首先,要從javax.servlet.HttpServletRequest
獲取org.eclipse.jetty.server.Request
只需使用 ...
Request baseRequest = Request.getBaseRequest(httpServletRequest);
但這不會讓你走得很遠。
org.eclipse.jetty.server.HttpChannel
和org.eclipse.jetty.io.EndPoint
不會將 NIO 接口或行為暴露給應用程序。
它們是通過單個接口實現 HTTP 規范行為的內部類,以處理諸如...
這正是 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
)這么說。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.